summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/man4/Makefile4
-rw-r--r--share/man/man4/man4.hppa/gsc.48
-rw-r--r--share/man/man4/man4.hppa/intro.414
-rw-r--r--share/man/man4/man4.hppa/io.49
-rw-r--r--share/man/man4/oosiop.4124
-rw-r--r--share/man/man4/osiop.418
-rw-r--r--share/man/man4/scsi.48
-rw-r--r--share/man/man4/siop.412
-rw-r--r--sys/arch/hppa/conf/GENERIC6
-rw-r--r--sys/arch/hppa/conf/RAMDISK6
-rw-r--r--sys/arch/hppa/conf/files.hppa5
-rw-r--r--sys/arch/hppa/gsc/oosiop_gsc.c169
-rw-r--r--sys/arch/hppa/gsc/osiop_gsc.c26
-rw-r--r--sys/dev/ic/oosiop.c1378
-rw-r--r--sys/dev/ic/oosiopreg.h324
-rw-r--r--sys/dev/ic/oosiopvar.h164
-rw-r--r--sys/dev/microcode/siop/Makefile11
-rw-r--r--sys/dev/microcode/siop/ncr53cxxx.c10
-rw-r--r--sys/dev/microcode/siop/oosiop.ss150
19 files changed, 2392 insertions, 54 deletions
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 0fc31321be8..ffd72d40495 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.255 2004/03/06 03:40:24 krw Exp $
+# $OpenBSD: Makefile,v 1.256 2004/03/12 00:04:51 miod Exp $
MAN= aac.4 ac97.4 acphy.4 addcom.4 adv.4 aha.4 ahb.4 ahc.4 \
aic.4 amdpm.4 ami.4 amphy.4 an.4 aria.4 ast.4 atalk.4 \
@@ -19,7 +19,7 @@ MAN= aac.4 ac97.4 acphy.4 addcom.4 adv.4 aha.4 ahb.4 ahc.4 \
mii.4 mpt.4 mpu.4 mtd.4 mtdphy.4 mtio.4 ncr.4 ne.4 neo.4 \
netintro.4 nge.4 noct.4 nofn.4 ns.4 nsclpcsio.4 nsgphy.4 \
nsip.4 nsphy.4 nsphyter.4 null.4 ohci.4 opl.4 options.4 \
- osiop.4 pcdisplay.4 pchb.4 pci.4 pciide.4 pckbc.4 \
+ oosiop.4 osiop.4 pcdisplay.4 pchb.4 pci.4 pciide.4 pckbc.4 \
pckbd.4 pcmcia.4 pcppi.4 pcscp.4 pf.4 pflog.4 pfsync.4 \
pms.4 ppb.4 ppp.4 pty.4 puc.4 qsphy.4 radio.4 raid.4 \
random.4 ray.4 rd.4 rl.4 rln.4 rlphy.4 route.4 rt.4 \
diff --git a/share/man/man4/man4.hppa/gsc.4 b/share/man/man4/man4.hppa/gsc.4
index 63c00eac70e..56582cf5714 100644
--- a/share/man/man4/man4.hppa/gsc.4
+++ b/share/man/man4/man4.hppa/gsc.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: gsc.4,v 1.17 2003/06/19 20:27:19 deraadt Exp $
+.\" $OpenBSD: gsc.4,v 1.18 2004/03/12 00:04:56 miod Exp $
.\"
.\"
.\" Copyright (c) 1999 Michael Shalayeff
@@ -78,8 +78,12 @@ Human Interface Loop, for HP-proprietary input devices like keyboard and mice.
Intel i82596 DX/CA 32-bit LAN coprocessor.
.It Xr lpt 4
Centronics printer port.
+.It Xr oosiop 4
+.Tn Symbios/NCR
+53C700 SCSI I/O Processor.
.It Xr osiop 4
-SCSI I/O processor.
+.Tn Symbios/NCR
+53C710 SCSI I/O Processor.
.El
.Pp
Some of these
diff --git a/share/man/man4/man4.hppa/intro.4 b/share/man/man4/man4.hppa/intro.4
index 0ef2a30d8f7..98c3780be09 100644
--- a/share/man/man4/man4.hppa/intro.4
+++ b/share/man/man4/man4.hppa/intro.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: intro.4,v 1.2 2004/01/15 15:10:00 mickey Exp $
+.\" $OpenBSD: intro.4,v 1.3 2004/03/12 00:04:56 miod Exp $
.\"
.\" Copyright (c) 2002,2003 Paul Weissmann
.\" All rights reserved.
@@ -247,10 +247,12 @@ The Centronics printer port.
The
.Xr eisa 4
bus controller on most of the older 700 machines.
+.It Xr oosiop 4
+.Tn Symbios/NCR
+53C700 SCSI I/O processor.
.It Xr osiop 4
-The
-.Tn NCR 53c7x0 SCSI
-I/O processor.
+.Tn Symbios/NCR
+53C710 SCSI I/O processor.
.It Xr pdc 4
The PROM interface, allows to call the routines in the machine's
PROM for things like initial console output and such.
@@ -258,8 +260,8 @@ PROM for things like initial console output and such.
The power button interface allowing graceful shutdown of the
system should being depressed on the running system.
.It Xr siop 4
-.Tn LSI/Symbios Logic/NCR 53c8xx SCSI
-I/O processor.
+.Tn LSI/Symbios Logic/NCR
+53C8xx SCSI I/O processor.
.It Xr sti 4
The system graphics driver.
.It Xr wax 4
diff --git a/share/man/man4/man4.hppa/io.4 b/share/man/man4/man4.hppa/io.4
index 540f7505631..e43753a4550 100644
--- a/share/man/man4/man4.hppa/io.4
+++ b/share/man/man4/man4.hppa/io.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: io.4,v 1.4 2004/01/15 19:37:52 jmc Exp $
+.\" $OpenBSD: io.4,v 1.5 2004/03/12 00:04:56 miod Exp $
.\"
.\" Copyright (c) 2003,2004 Paul Weissmann
.\" All rights reserved.
@@ -92,9 +92,11 @@ SCSI bus configuration:
.Pp
.Bl -tag -width XXXX -compact -offset indent
.It SE
+.Xr oosiop 4
+or
.Xr osiop 4 ;
-.Tn NCR53C700/710
-8-bit (fast) single-ended,
+.Tn Symbios/NCR
+53C700/710 8-bit (fast) single-ended,
.It FWD
.Xr siop 4 ;
.Tn NCR53C720
@@ -135,6 +137,7 @@ Formac+ FDDI,
.Xr ie 4 ,
.Xr intro 4 ,
.Xr lasi 4 ,
+.Xr oosiop 4 ,
.Xr osiop 4 ,
.Xr siop 4 ,
.Xr sti 4 ,
diff --git a/share/man/man4/oosiop.4 b/share/man/man4/oosiop.4
new file mode 100644
index 00000000000..b00cbc4e168
--- /dev/null
+++ b/share/man/man4/oosiop.4
@@ -0,0 +1,124 @@
+.\" $OpenBSD: oosiop.4,v 1.1 2004/03/12 00:04:51 miod Exp $
+.\" $NetBSD: osiop.4,v 1.2 2001/09/22 01:44:55 wiz Exp $
+.\"
+.\" Copyright (c) 2001 Izumi Tsutsui. 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. 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.
+.\"
+.Dd March 12, 2004
+.Dt OOSIOP 4
+.Os
+.Sh NAME
+.Nm oosiop
+.Nd Symbios/NCR 53C700 SCSI driver
+.Sh SYNOPSIS
+.Cd "# hppa"
+.Cd "oosiop* at gsc? irq 9"
+.Pp
+.Cd "scsibus* at oosiop?"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the
+.Tn Symbios/NCR
+53C700
+.Tn SCSI
+controller chip.
+.Pp
+The
+.Tn Symbios/NCR
+53C710
+.Tn SCSI
+controller is handled by the
+.Xr osiop 4
+driver, while the
+.Tn Symbios/NCR
+53C8xx
+.Tn PCI
+.Tn SCSI
+host adapters are handled by the
+.Xr siop 4
+driver.
+.\" .Sh CONFIGURATION
+.\" The
+.\" .Nm
+.\" driver supports the following
+.\" .Sy flags
+.\" for use in
+.\" .Xr config 8
+.\" files:
+.\" .Pp
+.\" .Bl -tag -compact -width "bits 8-15:"
+.\" .It bits 0-7 :
+.\" disable disconnect/reselect for the corresponding
+.\" .Tn SCSI
+.\" target
+.\" .It bits 8-15 :
+.\" disable synchronous negotiation for
+.\" .Tn SCSI
+.\" target
+.\" .It bits 16 :
+.\" disable DMA interrupts
+.\" .El
+.\" .Pp
+.\" .Qq Target
+.\" is synonymous with
+.\" .Tn SCSI
+.\" ID number.
+.\" .Pp
+.\" Note that
+.\" .Tn SCSI
+.\" tape drives should be allowed to perform disconnect/reselect or performance
+.\" will suffer.
+.\" .Sh BUGS
+.\" Neither
+.\" .Tn DMA
+.\" or synchronous data transfers are currently supported.
+.Sh SEE ALSO
+.Xr cd 4 ,
+.Xr ch 4 ,
+.Xr intro 4 ,
+.Xr osiop 4 ,
+.Xr scsi 4 ,
+.Xr sd 4 ,
+.Xr siop 4 ,
+.Xr ss 4 ,
+.Xr st 4 ,
+.Xr uk 4
+.Pp
+.Pa http://www.lsilogic.com/techlib/techdocs/storage_stand_prod/
+.Sh HISTORY
+.Nm
+driver first appeared in
+.Nx 1.6 ,
+and was ported to
+.Ox 3.5 .
+.Pp
+The original
+.Tn NCR
+53C710
+driver appeared in
+.Nx
+1.0 amiga port, and Izumi Tsutsui
+.Aq tsutsui@ceres.dti.ne.jp
+modified the driver and made it machine-independent.
diff --git a/share/man/man4/osiop.4 b/share/man/man4/osiop.4
index f8fbe41b2d0..8eb266bb6ea 100644
--- a/share/man/man4/osiop.4
+++ b/share/man/man4/osiop.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: osiop.4,v 1.3 2003/06/19 20:29:51 deraadt Exp $
+.\" $OpenBSD: osiop.4,v 1.4 2004/03/12 00:04:51 miod Exp $
.\" $NetBSD: osiop.4,v 1.2 2001/09/22 01:44:55 wiz Exp $
.\"
.\" Copyright (c) 2001 Izumi Tsutsui. All rights reserved.
@@ -25,7 +25,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd May 12, 2001
+.Dd March 12, 2004
.Dt OSIOP 4
.Os
.Sh NAME
@@ -33,8 +33,7 @@
.Nd Symbios/NCR 53C710 SCSI driver
.Sh SYNOPSIS
.Cd "# hppa"
-.Cd "osiop0 at gsc? irq 9"
-.Cd "osiop1 at gsc? irq 3"
+.Cd "osiop* at gsc? irq 9"
.Pp
.Cd "scsibus* at osiop?"
.Sh DESCRIPTION
@@ -46,18 +45,18 @@ driver provides support for the
.Tn SCSI
controller chip.
.Pp
-This driver does not support the
+The
.Tn Symbios/NCR
53C700
.Tn SCSI
-controller.
-.Pp
-For the
+controller is handled by the
+.Xr oosiop 4
+driver, while the
.Tn Symbios/NCR
53C8xx
.Tn PCI
.Tn SCSI
-host adapters, use the
+host adapters are handled by the
.Xr siop 4
driver.
.Sh CONFIGURATION
@@ -99,6 +98,7 @@ will suffer.
.Xr cd 4 ,
.Xr ch 4 ,
.Xr intro 4 ,
+.Xr oosiop 4 ,
.Xr scsi 4 ,
.Xr sd 4 ,
.Xr siop 4 ,
diff --git a/share/man/man4/scsi.4 b/share/man/man4/scsi.4
index d6a8c112cd3..4eeb6e08df6 100644
--- a/share/man/man4/scsi.4
+++ b/share/man/man4/scsi.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: scsi.4,v 1.15 2004/03/08 18:24:35 miod Exp $
+.\" $OpenBSD: scsi.4,v 1.16 2004/03/12 00:04:51 miod Exp $
.\"
.\" Copyright (c) 1996
.\" Julian Elischer <julian@freebsd.org>. All rights reserved.
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 4, 1996
+.Dd March 12, 2004
.Dt SCSI 4
.Os
.Sh NAME
@@ -51,6 +51,8 @@
.Cd "scsibus at isp?"
.Cd "scsibus at mpt?"
.Cd "scsibus at ncr?"
+.Cd "scsibus at oosiop?"
+.Cd "scsibus at osiop?"
.Cd "scsibus at pcscp?"
.Cd "scsibus at siop?"
.Cd "scsibus at trm?"
@@ -221,6 +223,8 @@ shows more detailed information including DMA scatter-gather logs.
.Xr isp 4 ,
.Xr mpt 4 ,
.Xr ncr 4 ,
+.Xr oosiop 4 ,
+.Xr osiop 4 ,
.Xr pcscp 4 ,
.Xr sd 4 ,
.Xr ses 4 ,
diff --git a/share/man/man4/siop.4 b/share/man/man4/siop.4
index ff2d00947f9..dc91a2797a0 100644
--- a/share/man/man4/siop.4
+++ b/share/man/man4/siop.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: siop.4,v 1.8 2003/06/06 10:29:41 jmc Exp $
+.\" $OpenBSD: siop.4,v 1.9 2004/03/12 00:04:51 miod Exp $
.\" $NetBSD: siop.4,v 1.3 2000/10/23 16:38:10 bouyer Exp $
.\"
.\" Copyright (c) 2000 Manuel Bouyer.
@@ -30,7 +30,7 @@
.\" INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd May 15, 2000
+.Dd March 12, 2004
.Dt SIOP 4
.Os
.Sh NAME
@@ -90,11 +90,19 @@ supports at most Ultra2-Wide with this chip)
replaces the older
.Nm ncr
driver which supported most of these devices.
+.Pp
+Older 53C700 and 53C710 controllers are supported by the
+.Xr oosiop 4
+and
+.Xr osiop 4
+drivers, respectively.
.Sh SEE ALSO
.Xr cd 4 ,
.Xr ch 4 ,
.Xr intro 4 ,
.Xr ncr 4 ,
+.Xr oosiop 4 ,
+.Xr osiop 4 ,
.Xr pci 4 ,
.Xr scsi 4 ,
.Xr sd 4 ,
diff --git a/sys/arch/hppa/conf/GENERIC b/sys/arch/hppa/conf/GENERIC
index c9e80bb2ee2..69f9c4be934 100644
--- a/sys/arch/hppa/conf/GENERIC
+++ b/sys/arch/hppa/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.47 2004/02/26 02:29:56 mickey Exp $
+# $OpenBSD: GENERIC,v 1.48 2004/03/12 00:04:56 miod Exp $
# Machine architecture; required by config(8)
machine hppa
@@ -97,9 +97,11 @@ ie0 at gsc0 irq 8 # 82C596DX/CA ether
#ie* at isa? port 0x300 irq 10
#ie* at pci? dev ? function ?
#tms* at gsc? irq 10 # TMS380C26 Network Controller
-osiop* at gsc? irq 9 # NCR 53C700/710 (Narrow SE)
+osiop* at gsc? irq 9 # NCR 53C710 (Narrow SE)
#osiop* at eisa? slot ?
scsibus* at osiop?
+oosiop* at gsc? disable irq 9 # NCR 53C700 (Narrow SE)
+scsibus* at oosiop?
harmony* at gsc? irq 13 # Audio Type 2 (CS4215/AD1849)
audio* at harmony?
gsckbc* at gsc? irq 26
diff --git a/sys/arch/hppa/conf/RAMDISK b/sys/arch/hppa/conf/RAMDISK
index d04a4e8a6de..130806ac265 100644
--- a/sys/arch/hppa/conf/RAMDISK
+++ b/sys/arch/hppa/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.26 2003/12/29 23:27:04 mickey Exp $
+# $OpenBSD: RAMDISK,v 1.27 2004/03/12 00:04:57 miod Exp $
#
# Diskless kernel config
#
@@ -112,9 +112,11 @@ ie0 at gsc0 irq 8 # 82C596DX/CA ether
#ie* at isa? port 0x300 irq 10
#ie* at pci? dev ? function ?
#tms* at gsc? irq 10 # TMS380C26 Network Controller
-osiop* at gsc? irq 9 # NCR 53C700/710 (Narrow SE)
+osiop* at gsc? irq 9 # NCR 53C710 (Narrow SE)
#osiop* at eisa? slot ?
scsibus* at osiop?
+oosiop* at gsc? disable irq 9 # NCR 53C700 (Narrow SE)
+scsibus* at oosiop?
#harmony* at gsc? irq 13 # Audio Type 2 (CS4215/AD1849)
#audio* at harmony?
gsckbc* at gsc? irq 26
diff --git a/sys/arch/hppa/conf/files.hppa b/sys/arch/hppa/conf/files.hppa
index 23f3a60e089..4021d88bdec 100644
--- a/sys/arch/hppa/conf/files.hppa
+++ b/sys/arch/hppa/conf/files.hppa
@@ -1,4 +1,4 @@
-# $OpenBSD: files.hppa,v 1.50 2004/02/13 20:39:31 mickey Exp $
+# $OpenBSD: files.hppa,v 1.51 2004/03/12 00:04:57 miod Exp $
#
# hppa-specific configuration info
@@ -191,6 +191,9 @@ file arch/hppa/gsc/if_ie_gsc.c ie_gsc
attach osiop at gsc with osiop_gsc
file arch/hppa/gsc/osiop_gsc.c osiop_gsc
+attach oosiop at gsc with oosiop_gsc
+file arch/hppa/gsc/oosiop_gsc.c oosiop_gsc
+
attach hil at gsc with hil_gsc
file arch/hppa/gsc/hil_gsc.c hil_gsc
diff --git a/sys/arch/hppa/gsc/oosiop_gsc.c b/sys/arch/hppa/gsc/oosiop_gsc.c
new file mode 100644
index 00000000000..80cec2b516e
--- /dev/null
+++ b/sys/arch/hppa/gsc/oosiop_gsc.c
@@ -0,0 +1,169 @@
+/* $OpenBSD: oosiop_gsc.c,v 1.1 2004/03/12 00:04:57 miod Exp $ */
+/* $NetBSD: oosiop_gsc.c,v 1.2 2003/07/15 02:29:25 lukem Exp $ */
+
+/*
+ * Copyright (c) 2001 Matt Fredette. All rights reserved.
+ * Copyright (c) 2001,2002 Izumi Tsutsui. 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. 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 AUTHORS ``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 AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1998 Michael Shalayeff
+ * 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 Michael Shalayeff.
+ * 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 <sys/malloc.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
+#include <machine/cpu.h>
+#include <machine/intr.h>
+#include <machine/iomod.h>
+#include <machine/autoconf.h>
+#include <machine/bus.h>
+
+#include <dev/ic/oosiopreg.h>
+#include <dev/ic/oosiopvar.h>
+
+#include <hppa/dev/cpudevs.h>
+#include <hppa/gsc/gscbusvar.h>
+
+#define OOSIOP_GSC_RESET 0x0000
+#define OOSIOP_GSC_OFFSET 0x0100
+
+int oosiop_gsc_match(struct device *, void *, void *);
+void oosiop_gsc_attach(struct device *, struct device *, void *);
+int oosiop_gsc_intr(void *);
+
+struct cfattach oosiop_gsc_ca = {
+ sizeof(struct oosiop_softc), oosiop_gsc_match, oosiop_gsc_attach
+};
+
+int
+oosiop_gsc_match(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct gsc_attach_args *ga = aux;
+
+ if (ga->ga_type.iodc_type != HPPA_TYPE_FIO ||
+ ga->ga_type.iodc_sv_model != HPPA_FIO_SCSI)
+ return 0;
+
+ return 1;
+}
+
+void
+oosiop_gsc_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct oosiop_softc *sc = (void *)self;
+ struct gsc_attach_args *ga = aux;
+ bus_space_handle_t ioh;
+
+ sc->sc_bst = ga->ga_iot;
+ sc->sc_dmat = ga->ga_dmatag;
+ if (bus_space_map(sc->sc_bst, ga->ga_hpa,
+ OOSIOP_GSC_OFFSET + OOSIOP_NREGS, 0, &ioh))
+ panic("oosiop_gsc_attach: couldn't map I/O ports");
+ if (bus_space_subregion(sc->sc_bst, ioh,
+ OOSIOP_GSC_OFFSET, OOSIOP_NREGS, &sc->sc_bsh))
+ panic("oosiop_gsc_attach: couldn't get chip ports");
+
+ sc->sc_freq = ga->ga_ca.ca_pdc_iodc_read->filler2[14];
+ if (!sc->sc_freq)
+ sc->sc_freq = 50 * 1000000;
+
+ sc->sc_chip = OOSIOP_700;
+ sc->sc_id = 7; /* XXX */
+
+ /*
+ * Reset the SCSI subsystem.
+ */
+ bus_space_write_1(sc->sc_bst, ioh, OOSIOP_GSC_RESET, 0);
+ DELAY(1000);
+
+ /*
+ * Call common attachment
+ */
+#ifdef OOSIOP_DEBUG
+ {
+ extern int oosiop_debug;
+ oosiop_debug = -1;
+ }
+#endif /* OOSIOP_DEBUG */
+ oosiop_attach(sc);
+
+ (void)gsc_intr_establish((struct gsc_softc *)parent,
+ ga->ga_irq, IPL_BIO, oosiop_gsc_intr, sc, sc->sc_dev.dv_xname);
+}
+
+/*
+ * interrupt handler
+ */
+int
+oosiop_gsc_intr(arg)
+ void *arg;
+{
+ struct oosiop_softc *sc = arg;
+ int rv;
+
+ rv = oosiop_intr(sc);
+
+#ifdef USELEDS
+ ledctl(PALED_DISK, 0, 0);
+#endif
+
+ return (rv);
+}
diff --git a/sys/arch/hppa/gsc/osiop_gsc.c b/sys/arch/hppa/gsc/osiop_gsc.c
index f9b879148a0..c928bdd5dd0 100644
--- a/sys/arch/hppa/gsc/osiop_gsc.c
+++ b/sys/arch/hppa/gsc/osiop_gsc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: osiop_gsc.c,v 1.10 2004/02/13 21:28:19 mickey Exp $ */
+/* $OpenBSD: osiop_gsc.c,v 1.11 2004/03/12 00:04:57 miod Exp $ */
/* $NetBSD: osiop_gsc.c,v 1.6 2002/10/02 05:17:50 thorpej Exp $ */
/*
@@ -79,7 +79,7 @@
#include <hppa/gsc/gscbusvar.h>
/* #include <hppa/hppa/machdep.h> */
-#define OSIOP_GSC_RESET 0x0000
+#define OSIOP_GSC_RESET 0x0000
#define OSIOP_GSC_OFFSET 0x0100
int osiop_gsc_match(struct device *, void *, void *);
@@ -98,8 +98,7 @@ osiop_gsc_match(parent, match, aux)
struct gsc_attach_args *ga = aux;
if (ga->ga_type.iodc_type != HPPA_TYPE_FIO ||
- (ga->ga_type.iodc_sv_model != HPPA_FIO_GSCSI /* &&
- ga->ga_type.iodc_sv_model != HPPA_FIO_SCSI */))
+ ga->ga_type.iodc_sv_model != HPPA_FIO_GSCSI)
return 0;
return 1;
@@ -117,27 +116,20 @@ osiop_gsc_attach(parent, self, aux)
sc->sc_bst = ga->ga_iot;
sc->sc_dmat = ga->ga_dmatag;
if (bus_space_map(sc->sc_bst, ga->ga_hpa,
- OSIOP_GSC_OFFSET + OSIOP_NREGS, 0, &ioh))
+ OSIOP_GSC_OFFSET + OSIOP_NREGS, 0, &ioh))
panic("osiop_gsc_attach: couldn't map I/O ports");
if (bus_space_subregion(sc->sc_bst, ioh,
- OSIOP_GSC_OFFSET, OSIOP_NREGS, &sc->sc_reg))
+ OSIOP_GSC_OFFSET, OSIOP_NREGS, &sc->sc_reg))
panic("osiop_gsc_attach: couldn't get chip ports");
sc->sc_clock_freq = ga->ga_ca.ca_pdc_iodc_read->filler2[14] / 1000000;
if (!sc->sc_clock_freq)
sc->sc_clock_freq = 50;
- if (ga->ga_ca.ca_type.iodc_sv_model == HPPA_FIO_GSCSI) {
- sc->sc_dcntl = OSIOP_DCNTL_EA;
- /* XXX set burst mode to 8 words (32 bytes) */
- sc->sc_ctest7 = OSIOP_CTEST7_CDIS;
- sc->sc_dmode = OSIOP_DMODE_BL8; /* | OSIOP_DMODE_FC2 */
- } else {
- sc->sc_dcntl = 0;
- sc->sc_ctest7 = 0;
- sc->sc_dmode = 0; /* | OSIOP_DMODE_FC2 */
- }
-
+ sc->sc_dcntl = OSIOP_DCNTL_EA;
+ /* XXX set burst mode to 8 words (32 bytes) */
+ sc->sc_ctest7 = OSIOP_CTEST7_CDIS;
+ sc->sc_dmode = OSIOP_DMODE_BL8; /* | OSIOP_DMODE_FC2 */
sc->sc_flags = 0;
sc->sc_id = 7; /* XXX */
diff --git a/sys/dev/ic/oosiop.c b/sys/dev/ic/oosiop.c
new file mode 100644
index 00000000000..dc633457488
--- /dev/null
+++ b/sys/dev/ic/oosiop.c
@@ -0,0 +1,1378 @@
+/* $OpenBSD: oosiop.c,v 1.1 2004/03/12 00:04:57 miod Exp $ */
+/* $NetBSD: oosiop.c,v 1.4 2003/10/29 17:45:55 tsutsui Exp $ */
+
+/*
+ * Copyright (c) 2001 Shuichiro URATA. 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. 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.
+ */
+
+/*
+ * NCR53C700 SCSI I/O processor (OOSIOP) driver
+ *
+ * TODO:
+ * - More better error handling.
+ * - Implement tagged queuing.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/timeout.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+#include <scsi/scsi_message.h>
+
+#include <machine/cpu.h>
+#include <machine/bus.h>
+
+#include <dev/ic/oosiopreg.h>
+#include <dev/ic/oosiopvar.h>
+
+/* 53C700 script */
+#include <dev/microcode/siop/oosiop.out>
+
+int oosiop_alloc_cb(struct oosiop_softc *, int);
+
+static __inline void oosiop_relocate_io(struct oosiop_softc *, bus_addr_t);
+static __inline void oosiop_relocate_tc(struct oosiop_softc *, bus_addr_t);
+static __inline void oosiop_fixup_select(struct oosiop_softc *, bus_addr_t,
+ int);
+static __inline void oosiop_fixup_jump(struct oosiop_softc *, bus_addr_t,
+ bus_addr_t);
+static __inline void oosiop_fixup_move(struct oosiop_softc *, bus_addr_t,
+ bus_size_t, bus_addr_t);
+
+void oosiop_load_script(struct oosiop_softc *);
+void oosiop_setup_sgdma(struct oosiop_softc *, struct oosiop_cb *);
+void oosiop_setup_dma(struct oosiop_softc *);
+void oosiop_flush_fifo(struct oosiop_softc *);
+void oosiop_clear_fifo(struct oosiop_softc *);
+void oosiop_phasemismatch(struct oosiop_softc *);
+void oosiop_setup_syncxfer(struct oosiop_softc *);
+void oosiop_set_syncparam(struct oosiop_softc *, int, int, int);
+void oosiop_minphys(struct buf *);
+int oosiop_scsicmd(struct scsi_xfer *);
+void oosiop_done(struct oosiop_softc *, struct oosiop_cb *);
+void oosiop_timeout(void *);
+void oosiop_reset(struct oosiop_softc *);
+void oosiop_reset_bus(struct oosiop_softc *);
+void oosiop_scriptintr(struct oosiop_softc *);
+void oosiop_msgin(struct oosiop_softc *, struct oosiop_cb *);
+
+/* Trap interrupt code for unexpected data I/O */
+#define DATAIN_TRAP 0xdead0001
+#define DATAOUT_TRAP 0xdead0002
+
+/* Possible TP and SCF conbination */
+static const struct {
+ u_int8_t tp;
+ u_int8_t scf;
+} synctbl[] = {
+ {0, 1}, /* SCLK / 4.0 */
+ {1, 1}, /* SCLK / 5.0 */
+ {2, 1}, /* SCLK / 6.0 */
+ {3, 1}, /* SCLK / 7.0 */
+ {1, 2}, /* SCLK / 7.5 */
+ {4, 1}, /* SCLK / 8.0 */
+ {5, 1}, /* SCLK / 9.0 */
+ {6, 1}, /* SCLK / 10.0 */
+ {3, 2}, /* SCLK / 10.5 */
+ {7, 1}, /* SCLK / 11.0 */
+ {4, 2}, /* SCLK / 12.0 */
+ {5, 2}, /* SCLK / 13.5 */
+ {3, 3}, /* SCLK / 14.0 */
+ {6, 2}, /* SCLK / 15.0 */
+ {4, 3}, /* SCLK / 16.0 */
+ {7, 2}, /* SCLK / 16.5 */
+ {5, 3}, /* SCLK / 18.0 */
+ {6, 3}, /* SCLK / 20.0 */
+ {7, 3} /* SCLK / 22.0 */
+};
+#define NSYNCTBL (sizeof(synctbl) / sizeof(synctbl[0]))
+
+#define oosiop_period(sc, tp, scf) \
+ (((1000000000 / (sc)->sc_freq) * (tp) * (scf)) / 40)
+
+struct cfdriver oosiop_cd = {
+ NULL, "oosiop", DV_DULL
+};
+
+struct scsi_adapter oosiop_adapter = {
+ oosiop_scsicmd,
+ oosiop_minphys,
+ NULL,
+ NULL
+};
+
+struct scsi_device oosiop_dev = {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+void
+oosiop_attach(struct oosiop_softc *sc)
+{
+ bus_size_t scrsize;
+ bus_dma_segment_t seg;
+ struct oosiop_cb *cb;
+ int err, i, nseg;
+
+ /*
+ * Allocate DMA-safe memory for the script and map it.
+ */
+ scrsize = round_page(sizeof(oosiop_script));
+ err = bus_dmamem_alloc(sc->sc_dmat, scrsize, PAGE_SIZE, 0, &seg, 1,
+ &nseg, BUS_DMA_NOWAIT);
+ if (err) {
+ printf(": failed to allocate script memory, err=%d\n", err);
+ return;
+ }
+ err = bus_dmamem_map(sc->sc_dmat, &seg, nseg, scrsize,
+ (caddr_t *)&sc->sc_scr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
+ if (err) {
+ printf(": failed to map script memory, err=%d\n", err);
+ return;
+ }
+ err = bus_dmamap_create(sc->sc_dmat, scrsize, 1, scrsize, 0,
+ BUS_DMA_NOWAIT, &sc->sc_scrdma);
+ if (err) {
+ printf(": failed to create script map, err=%d\n", err);
+ return;
+ }
+ err = bus_dmamap_load(sc->sc_dmat, sc->sc_scrdma, sc->sc_scr, scrsize,
+ NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE);
+ if (err) {
+ printf(": failed to load script map, err=%d\n", err);
+ return;
+ }
+ bzero(sc->sc_scr, scrsize);
+ sc->sc_scrbase = sc->sc_scrdma->dm_segs[0].ds_addr;
+
+ /* Initialize command block array */
+ TAILQ_INIT(&sc->sc_free_cb);
+ TAILQ_INIT(&sc->sc_cbq);
+ if (oosiop_alloc_cb(sc, OOSIOP_NCB) != 0)
+ return;
+
+ /* Use first cb to reselection msgin buffer */
+ cb = TAILQ_FIRST(&sc->sc_free_cb);
+ sc->sc_reselbuf = cb->xferdma->dm_segs[0].ds_addr +
+ offsetof(struct oosiop_xfer, msgin[0]);
+
+ for (i = 0; i < OOSIOP_NTGT; i++) {
+ sc->sc_tgt[i].nexus = NULL;
+ sc->sc_tgt[i].flags = 0;
+ }
+
+ /* Setup asynchronous clock divisor parameters */
+ if (sc->sc_freq <= 25000000) {
+ sc->sc_ccf = 10;
+ sc->sc_dcntl = OOSIOP_DCNTL_CF_1;
+ } else if (sc->sc_freq <= 37500000) {
+ sc->sc_ccf = 15;
+ sc->sc_dcntl = OOSIOP_DCNTL_CF_1_5;
+ } else if (sc->sc_freq <= 50000000) {
+ sc->sc_ccf = 20;
+ sc->sc_dcntl = OOSIOP_DCNTL_CF_2;
+ } else {
+ sc->sc_ccf = 30;
+ sc->sc_dcntl = OOSIOP_DCNTL_CF_3;
+ }
+
+ if (sc->sc_chip == OOSIOP_700)
+ sc->sc_minperiod = oosiop_period(sc, 4, sc->sc_ccf);
+ else
+ sc->sc_minperiod = oosiop_period(sc, 4, 10);
+
+ if (sc->sc_minperiod < 25)
+ sc->sc_minperiod = 25; /* limit to 10MB/s */
+
+ printf(": NCR53C700%s rev %d, %dMHz, SCSI ID %d\n",
+ sc->sc_chip == OOSIOP_700_66 ? "-66" : "",
+ oosiop_read_1(sc, OOSIOP_CTEST7) >> 4,
+ sc->sc_freq / 1000000, sc->sc_id);
+ /*
+ * Reset all
+ */
+ oosiop_reset(sc);
+ oosiop_reset_bus(sc);
+
+ /*
+ * Start SCRIPTS processor
+ */
+ oosiop_load_script(sc);
+ sc->sc_active = 0;
+ oosiop_write_4(sc, OOSIOP_DSP, sc->sc_scrbase + Ent_wait_reselect);
+
+ /*
+ * Fill in the sc_link.
+ */
+ sc->sc_link.adapter = &oosiop_adapter;
+ sc->sc_link.adapter_softc = sc;
+ sc->sc_link.device = &oosiop_dev;
+ sc->sc_link.openings = 4;
+ sc->sc_link.adapter_buswidth = OOSIOP_NTGT;
+ sc->sc_link.adapter_target = sc->sc_id;
+ sc->sc_link.quirks = ADEV_NODOORLOCK;
+
+ /*
+ * Now try to attach all the sub devices.
+ */
+ config_found(&sc->sc_dev, &sc->sc_link, scsiprint);
+}
+
+int
+oosiop_alloc_cb(struct oosiop_softc *sc, int ncb)
+{
+ struct oosiop_cb *cb;
+ struct oosiop_xfer *xfer;
+ bus_size_t xfersize;
+ bus_dma_segment_t seg;
+ int i, s, err, nseg;
+
+ /*
+ * Allocate oosiop_cb.
+ */
+ cb = malloc(sizeof(struct oosiop_cb) * ncb, M_DEVBUF, M_NOWAIT);
+ if (cb == NULL) {
+ printf(": failed to allocate cb memory\n");
+ return (ENOMEM);
+ }
+ bzero(cb, sizeof(struct oosiop_cb) * ncb);
+
+ /*
+ * Allocate DMA-safe memory for the oosiop_xfer and map it.
+ */
+ xfersize = sizeof(struct oosiop_xfer) * ncb;
+ err = bus_dmamem_alloc(sc->sc_dmat, xfersize, PAGE_SIZE, 0, &seg, 1,
+ &nseg, BUS_DMA_NOWAIT);
+ if (err) {
+ printf(": failed to allocate xfer block memory, err=%d\n", err);
+ return (err);
+ }
+ err = bus_dmamem_map(sc->sc_dmat, &seg, nseg, xfersize,
+ (caddr_t *)(void *)&xfer, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
+ if (err) {
+ printf(": failed to map xfer block memory, err=%d\n", err);
+ return (err);
+ }
+
+ /* Initialize each command block */
+ for (i = 0; i < ncb; i++) {
+ err = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE,
+ 0, BUS_DMA_NOWAIT, &cb->cmddma);
+ if (err) {
+ printf(": failed to create cmddma map, err=%d\n", err);
+ return (err);
+ }
+
+ err = bus_dmamap_create(sc->sc_dmat, OOSIOP_MAX_XFER,
+ OOSIOP_NSG, OOSIOP_DBC_MAX, 0, BUS_DMA_NOWAIT,
+ &cb->datadma);
+ if (err) {
+ printf(": failed to create datadma map, err=%d\n", err);
+ return (err);
+ }
+
+ err = bus_dmamap_create(sc->sc_dmat,
+ sizeof(struct oosiop_xfer), 1, sizeof(struct oosiop_xfer),
+ 0, BUS_DMA_NOWAIT, &cb->xferdma);
+ if (err) {
+ printf(": failed to create xfer block map, err=%d\n",
+ err);
+ return (err);
+ }
+ err = bus_dmamap_load(sc->sc_dmat, cb->xferdma, xfer,
+ sizeof(struct oosiop_xfer), NULL, BUS_DMA_NOWAIT);
+ if (err) {
+ printf(": failed to load xfer block, err=%d\n", err);
+ return (err);
+ }
+
+ cb->xfer = xfer;
+
+ s = splbio();
+ TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain);
+ splx(s);
+
+ cb++;
+ xfer++;
+ }
+
+ return (0);
+}
+
+static __inline void
+oosiop_relocate_io(struct oosiop_softc *sc, bus_addr_t addr)
+{
+ u_int32_t dcmd;
+ int32_t dsps;
+
+ dcmd = letoh32(sc->sc_scr[addr / 4 + 0]);
+ dsps = letoh32(sc->sc_scr[addr / 4 + 1]);
+
+ /* convert relative to absolute */
+ if (dcmd & 0x04000000) {
+ dcmd &= ~0x04000000;
+#if 0
+ /*
+ * sign extension isn't needed here because
+ * ncr53cxxx.c generates 32 bit dsps.
+ */
+ dsps <<= 8;
+ dsps >>= 8;
+#endif
+ sc->sc_scr[addr / 4 + 0] = htole32(dcmd);
+ dsps += addr + 8;
+ }
+
+ sc->sc_scr[addr / 4 + 1] = htole32(dsps + sc->sc_scrbase);
+}
+
+static __inline void
+oosiop_relocate_tc(struct oosiop_softc *sc, bus_addr_t addr)
+{
+ u_int32_t dcmd;
+ int32_t dsps;
+
+ dcmd = letoh32(sc->sc_scr[addr / 4 + 0]);
+ dsps = letoh32(sc->sc_scr[addr / 4 + 1]);
+
+ /* convert relative to absolute */
+ if (dcmd & 0x00800000) {
+ dcmd &= ~0x00800000;
+ sc->sc_scr[addr / 4] = htole32(dcmd);
+#if 0
+ /*
+ * sign extension isn't needed here because
+ * ncr53cxxx.c generates 32 bit dsps.
+ */
+ dsps <<= 8;
+ dsps >>= 8;
+#endif
+ dsps += addr + 8;
+ }
+
+ sc->sc_scr[addr / 4 + 1] = htole32(dsps + sc->sc_scrbase);
+}
+
+static __inline void
+oosiop_fixup_select(struct oosiop_softc *sc, bus_addr_t addr, int id)
+{
+ u_int32_t dcmd;
+
+ dcmd = letoh32(sc->sc_scr[addr / 4]);
+ dcmd &= 0xff00ffff;
+ dcmd |= 0x00010000 << id;
+ sc->sc_scr[addr / 4] = htole32(dcmd);
+}
+
+static __inline void
+oosiop_fixup_jump(struct oosiop_softc *sc, bus_addr_t addr, bus_addr_t dst)
+{
+
+ sc->sc_scr[addr / 4 + 1] = htole32(dst);
+}
+
+static __inline void
+oosiop_fixup_move(struct oosiop_softc *sc, bus_addr_t addr, bus_size_t dbc,
+ bus_addr_t dsps)
+{
+ u_int32_t dcmd;
+
+ dcmd = letoh32(sc->sc_scr[addr / 4]);
+ dcmd &= 0xff000000;
+ dcmd |= dbc & 0x00ffffff;
+ sc->sc_scr[addr / 4 + 0] = htole32(dcmd);
+ sc->sc_scr[addr / 4 + 1] = htole32(dsps);
+}
+
+void
+oosiop_load_script(struct oosiop_softc *sc)
+{
+ int i;
+
+ /* load script */
+ for (i = 0; i < sizeof(oosiop_script) / sizeof(oosiop_script[0]); i++)
+ sc->sc_scr[i] = htole32(oosiop_script[i]);
+
+ /* relocate script */
+ for (i = 0; i < (sizeof(oosiop_script) / 8); i++) {
+ switch (oosiop_script[i * 2] >> 27) {
+ case 0x08: /* select */
+ case 0x0a: /* wait reselect */
+ oosiop_relocate_io(sc, i * 8);
+ break;
+ case 0x10: /* jump */
+ case 0x11: /* call */
+ oosiop_relocate_tc(sc, i * 8);
+ break;
+ }
+ }
+
+ oosiop_fixup_move(sc, Ent_p_resel_msgin_move, 1, sc->sc_reselbuf);
+ OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_PREWRITE);
+}
+
+void
+oosiop_setup_sgdma(struct oosiop_softc *sc, struct oosiop_cb *cb)
+{
+ struct oosiop_xfer *xfer = cb->xfer;
+ struct scsi_xfer *xs = cb->xs;
+ int i, n, off;
+
+ OOSIOP_XFERSCR_SYNC(sc, cb,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ off = cb->curdp;
+
+ if (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
+ /* Find start segment */
+ for (i = 0; i < cb->datadma->dm_nsegs; i++) {
+ if (off < cb->datadma->dm_segs[i].ds_len)
+ break;
+ off -= cb->datadma->dm_segs[i].ds_len;
+ }
+
+ /* build MOVE block */
+ if (xs->flags & SCSI_DATA_IN) {
+ n = 0;
+ while (i < cb->datadma->dm_nsegs) {
+ xfer->datain_scr[n * 2 + 0] =
+ htole32(0x09000000 |
+ (cb->datadma->dm_segs[i].ds_len - off));
+ xfer->datain_scr[n * 2 + 1] =
+ htole32(cb->datadma->dm_segs[i].ds_addr +
+ off);
+ n++;
+ i++;
+ off = 0;
+ }
+ xfer->datain_scr[n * 2 + 0] = htole32(0x80080000);
+ xfer->datain_scr[n * 2 + 1] =
+ htole32(sc->sc_scrbase + Ent_phasedispatch);
+ }
+ if (xs->flags & SCSI_DATA_OUT) {
+ n = 0;
+ while (i < cb->datadma->dm_nsegs) {
+ xfer->dataout_scr[n * 2 + 0] =
+ htole32(0x08000000 |
+ (cb->datadma->dm_segs[i].ds_len - off));
+ xfer->dataout_scr[n * 2 + 1] =
+ htole32(cb->datadma->dm_segs[i].ds_addr +
+ off);
+ n++;
+ i++;
+ off = 0;
+ }
+ xfer->dataout_scr[n * 2 + 0] = htole32(0x80080000);
+ xfer->dataout_scr[n * 2 + 1] =
+ htole32(sc->sc_scrbase + Ent_phasedispatch);
+ }
+ }
+ if ((xs->flags & SCSI_DATA_IN) == 0) {
+ xfer->datain_scr[0] = htole32(0x98080000);
+ xfer->datain_scr[1] = htole32(DATAIN_TRAP);
+ }
+ if ((xs->flags & SCSI_DATA_OUT) == 0) {
+ xfer->dataout_scr[0] = htole32(0x98080000);
+ xfer->dataout_scr[1] = htole32(DATAOUT_TRAP);
+ }
+ OOSIOP_XFERSCR_SYNC(sc, cb,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+}
+
+/*
+ * Setup DMA pointer into script.
+ */
+void
+oosiop_setup_dma(struct oosiop_softc *sc)
+{
+ struct oosiop_cb *cb;
+ bus_addr_t xferbase;
+
+ cb = sc->sc_curcb;
+ xferbase = cb->xferdma->dm_segs[0].ds_addr;
+
+ OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_POSTWRITE);
+
+ oosiop_fixup_select(sc, Ent_p_select, cb->id);
+ oosiop_fixup_jump(sc, Ent_p_datain_jump, xferbase +
+ offsetof(struct oosiop_xfer, datain_scr[0]));
+ oosiop_fixup_jump(sc, Ent_p_dataout_jump, xferbase +
+ offsetof(struct oosiop_xfer, dataout_scr[0]));
+ oosiop_fixup_move(sc, Ent_p_msgin_move, 1, xferbase +
+ offsetof(struct oosiop_xfer, msgin[0]));
+ oosiop_fixup_move(sc, Ent_p_extmsglen_move, 1, xferbase +
+ offsetof(struct oosiop_xfer, msgin[1]));
+ oosiop_fixup_move(sc, Ent_p_msgout_move, cb->msgoutlen, xferbase +
+ offsetof(struct oosiop_xfer, msgout[0]));
+ oosiop_fixup_move(sc, Ent_p_status_move, 1, xferbase +
+ offsetof(struct oosiop_xfer, status));
+ oosiop_fixup_move(sc, Ent_p_cmdout_move, cb->xs->cmdlen,
+ cb->cmddma->dm_segs[0].ds_addr);
+
+ OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_PREWRITE);
+}
+
+void
+oosiop_flush_fifo(struct oosiop_softc *sc)
+{
+
+ oosiop_write_1(sc, OOSIOP_DFIFO, oosiop_read_1(sc, OOSIOP_DFIFO) |
+ OOSIOP_DFIFO_FLF);
+ while ((oosiop_read_1(sc, OOSIOP_CTEST1) & OOSIOP_CTEST1_FMT) !=
+ OOSIOP_CTEST1_FMT)
+ ;
+ oosiop_write_1(sc, OOSIOP_DFIFO, oosiop_read_1(sc, OOSIOP_DFIFO) &
+ ~OOSIOP_DFIFO_FLF);
+}
+
+void
+oosiop_clear_fifo(struct oosiop_softc *sc)
+{
+
+ oosiop_write_1(sc, OOSIOP_DFIFO, oosiop_read_1(sc, OOSIOP_DFIFO) |
+ OOSIOP_DFIFO_CLF);
+ while ((oosiop_read_1(sc, OOSIOP_CTEST1) & OOSIOP_CTEST1_FMT) !=
+ OOSIOP_CTEST1_FMT)
+ ;
+ oosiop_write_1(sc, OOSIOP_DFIFO, oosiop_read_1(sc, OOSIOP_DFIFO) &
+ ~OOSIOP_DFIFO_CLF);
+}
+
+void
+oosiop_phasemismatch(struct oosiop_softc *sc)
+{
+ struct oosiop_cb *cb;
+ u_int32_t dsp, dbc, n, i, len;
+ u_int8_t dfifo, sstat1;
+
+ cb = sc->sc_curcb;
+ if (cb == NULL)
+ return;
+
+ dsp = oosiop_read_4(sc, OOSIOP_DSP);
+ dbc = oosiop_read_4(sc, OOSIOP_DBC) & OOSIOP_DBC_MAX;
+ len = 0;
+
+ n = dsp - cb->xferdma->dm_segs[0].ds_addr - 8;
+ if (n >= offsetof(struct oosiop_xfer, datain_scr[0]) &&
+ n < offsetof(struct oosiop_xfer, datain_scr[OOSIOP_NSG * 2])) {
+ n -= offsetof(struct oosiop_xfer, datain_scr[0]);
+ n >>= 3;
+ OOSIOP_DINSCR_SYNC(sc, cb,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ for (i = 0; i <= n; i++)
+ len += letoh32(cb->xfer->datain_scr[i * 2]) &
+ 0x00ffffff;
+ OOSIOP_DINSCR_SYNC(sc, cb,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ /* All data in the chip are already flushed */
+ } else if (n >= offsetof(struct oosiop_xfer, dataout_scr[0]) &&
+ n < offsetof(struct oosiop_xfer, dataout_scr[OOSIOP_NSG * 2])) {
+ n -= offsetof(struct oosiop_xfer, dataout_scr[0]);
+ n >>= 3;
+ OOSIOP_DOUTSCR_SYNC(sc, cb,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ for (i = 0; i <= n; i++)
+ len += letoh32(cb->xfer->dataout_scr[i * 2]) &
+ 0x00ffffff;
+ OOSIOP_DOUTSCR_SYNC(sc, cb,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ dfifo = oosiop_read_1(sc, OOSIOP_DFIFO);
+ dbc += ((dfifo & OOSIOP_DFIFO_BO) - (dbc & OOSIOP_DFIFO_BO)) &
+ OOSIOP_DFIFO_BO;
+
+ sstat1 = oosiop_read_1(sc, OOSIOP_SSTAT1);
+ if (sstat1 & OOSIOP_SSTAT1_OLF)
+ dbc++;
+ if ((sc->sc_tgt[cb->id].sxfer != 0) &&
+ (sstat1 & OOSIOP_SSTAT1_ORF) != 0)
+ dbc++;
+
+ oosiop_clear_fifo(sc);
+ } else {
+ printf("%s: phase mismatch addr=%08x\n", sc->sc_dev.dv_xname,
+ oosiop_read_4(sc, OOSIOP_DSP) - 8);
+ oosiop_clear_fifo(sc);
+ return;
+ }
+
+ len -= dbc;
+ if (len) {
+ cb->curdp += len;
+ oosiop_setup_sgdma(sc, cb);
+ }
+}
+
+void
+oosiop_setup_syncxfer(struct oosiop_softc *sc)
+{
+ int id;
+
+ id = sc->sc_curcb->id;
+ if (sc->sc_chip != OOSIOP_700)
+ oosiop_write_1(sc, OOSIOP_SBCL, sc->sc_tgt[id].scf);
+
+ oosiop_write_1(sc, OOSIOP_SXFER, sc->sc_tgt[id].sxfer);
+}
+
+void
+oosiop_set_syncparam(struct oosiop_softc *sc, int id, int period, int offset)
+{
+ int i, p;
+
+ printf("%s: target %d now using 8 bit ", sc->sc_dev.dv_xname, id);
+
+ if (offset == 0) {
+ /* Asynchronous */
+ sc->sc_tgt[id].scf = 0;
+ sc->sc_tgt[id].sxfer = 0;
+ printf("asynchronous");
+ } else {
+ /* Synchronous */
+ if (sc->sc_chip == OOSIOP_700) {
+ for (i = 4; i < 12; i++) {
+ p = oosiop_period(sc, i, sc->sc_ccf);
+ if (p >= period)
+ break;
+ }
+ if (i == 12) {
+ printf("%s: target %d period too large\n",
+ sc->sc_dev.dv_xname, id);
+ i = 11; /* XXX */
+ }
+ sc->sc_tgt[id].scf = 0;
+ sc->sc_tgt[id].sxfer = ((i - 4) << 4) | offset;
+ } else {
+ for (i = 0; i < NSYNCTBL; i++) {
+ p = oosiop_period(sc, synctbl[i].tp + 4,
+ (synctbl[i].scf + 1) * 5);
+ if (p >= period)
+ break;
+ }
+ if (i == NSYNCTBL) {
+ printf("%s: target %d period too large\n",
+ sc->sc_dev.dv_xname, id);
+ i = NSYNCTBL - 1; /* XXX */
+ }
+ sc->sc_tgt[id].scf = synctbl[i].scf;
+ sc->sc_tgt[id].sxfer = (synctbl[i].tp << 4) | offset;
+ }
+ /* XXX print actual ns period... */
+ printf(" synchronous");
+ }
+ printf(" xfers\n");
+}
+
+void
+oosiop_minphys(struct buf *bp)
+{
+
+ if (bp->b_bcount > OOSIOP_MAX_XFER)
+ bp->b_bcount = OOSIOP_MAX_XFER;
+ minphys(bp);
+}
+
+int
+oosiop_scsicmd(struct scsi_xfer *xs)
+{
+ struct oosiop_softc *sc;
+ struct oosiop_cb *cb;
+ struct oosiop_xfer *xfer;
+ int s, err;
+
+ sc = (struct oosiop_softc *)xs->sc_link->adapter_softc;
+
+ s = splbio();
+ cb = TAILQ_FIRST(&sc->sc_free_cb);
+ TAILQ_REMOVE(&sc->sc_free_cb, cb, chain);
+ splx(s);
+
+ cb->xs = xs;
+ cb->xsflags = xs->flags;
+ cb->datalen = xs->datalen;
+ cb->flags = 0;
+ cb->id = xs->sc_link->target;
+ cb->lun = xs->sc_link->lun;
+ cb->curdp = 0;
+ cb->savedp = 0;
+ xfer = cb->xfer;
+
+ /* Setup SCSI command buffer DMA */
+ err = bus_dmamap_load(sc->sc_dmat, cb->cmddma, xs->cmd,
+ xs->cmdlen, NULL, ((xs->flags & SCSI_NOSLEEP) ?
+ BUS_DMA_NOWAIT : BUS_DMA_WAITOK) | BUS_DMA_WRITE);
+ if (err) {
+ printf("%s: unable to load cmd DMA map: %d",
+ sc->sc_dev.dv_xname, err);
+ xs->error = XS_DRIVER_STUFFUP;
+ TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain);
+ scsi_done(xs);
+ return (COMPLETE);
+ }
+ bus_dmamap_sync(sc->sc_dmat, cb->cmddma, 0, xs->cmdlen,
+ BUS_DMASYNC_PREWRITE);
+
+ /* Setup data buffer DMA */
+ if (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
+ err = bus_dmamap_load(sc->sc_dmat, cb->datadma,
+ xs->data, xs->datalen, NULL,
+ ((xs->flags & SCSI_NOSLEEP) ?
+ BUS_DMA_NOWAIT : BUS_DMA_WAITOK) |
+ BUS_DMA_STREAMING |
+ ((xs->flags & SCSI_DATA_IN) ? BUS_DMA_READ :
+ BUS_DMA_WRITE));
+ if (err) {
+ printf("%s: unable to load data DMA map: %d",
+ sc->sc_dev.dv_xname, err);
+ xs->error = XS_DRIVER_STUFFUP;
+ bus_dmamap_unload(sc->sc_dmat, cb->cmddma);
+ TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain);
+ scsi_done(xs);
+ return (COMPLETE);
+ }
+ bus_dmamap_sync(sc->sc_dmat, cb->datadma,
+ 0, xs->datalen,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ }
+
+ oosiop_setup_sgdma(sc, cb);
+
+ /* Setup msgout buffer */
+ OOSIOP_XFERMSG_SYNC(sc, cb,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ xfer->msgout[0] = MSG_IDENTIFY(cb->lun,
+ (cb->xfer->scsi_cmd.opcode != REQUEST_SENSE));
+ cb->msgoutlen = 1;
+
+ if (sc->sc_tgt[cb->id].flags & TGTF_SYNCNEG) {
+ /* Send SDTR */
+ xfer->msgout[1] = MSG_EXTENDED;
+ xfer->msgout[2] = MSG_EXT_SDTR_LEN;
+ xfer->msgout[3] = MSG_EXT_SDTR;
+ xfer->msgout[4] = sc->sc_minperiod;
+ xfer->msgout[5] = OOSIOP_MAX_OFFSET;
+ cb->msgoutlen = 6;
+ sc->sc_tgt[cb->id].flags &= ~TGTF_SYNCNEG;
+ sc->sc_tgt[cb->id].flags |= TGTF_WAITSDTR;
+ }
+
+ xfer->status = SCSI_OOSIOP_NOSTATUS;
+
+ OOSIOP_XFERMSG_SYNC(sc, cb,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ s = splbio();
+
+ /*
+ * Always initialize timeout so it does not contain trash
+ * that could confuse timeout_del().
+ */
+ timeout_set(&xs->stimeout, oosiop_timeout, cb);
+
+ TAILQ_INSERT_TAIL(&sc->sc_cbq, cb, chain);
+
+ if (!sc->sc_active) {
+ /* Abort script to start selection */
+ oosiop_write_1(sc, OOSIOP_ISTAT, OOSIOP_ISTAT_ABRT);
+ }
+ if (xs->flags & SCSI_POLL) {
+ /* Poll for command completion */
+ while ((xs->flags & ITSDONE) == 0) {
+ delay(1000);
+ oosiop_intr(sc);
+ }
+ } else {
+ /* start expire timer */
+ timeout_add(&xs->stimeout, (xs->timeout / 1000) * hz);
+ }
+
+ splx(s);
+
+ if ((xs->flags & ITSDONE) == 0)
+ return (SUCCESSFULLY_QUEUED);
+ else
+ return (COMPLETE);
+}
+
+void
+oosiop_done(struct oosiop_softc *sc, struct oosiop_cb *cb)
+{
+ struct scsi_xfer *xs;
+ struct scsi_link *periph;
+ int autosense;
+
+ xs = cb->xs;
+ periph = xs->sc_link;
+
+ /*
+ * Record if this is the completion of an auto sense
+ * scsi command, and then reset the flag so we don't loop
+ * when such a command fails or times out.
+ */
+ autosense = cb->flags & CBF_AUTOSENSE;
+ cb->flags &= ~CBF_AUTOSENSE;
+
+ if (cb == sc->sc_curcb)
+ sc->sc_curcb = NULL;
+ if (cb == sc->sc_lastcb)
+ sc->sc_lastcb = NULL;
+ sc->sc_tgt[cb->id].nexus = NULL;
+
+ if (cb->datalen > 0) {
+ bus_dmamap_sync(sc->sc_dmat, cb->datadma, 0, xs->datalen,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->sc_dmat, cb->datadma);
+ }
+
+ timeout_del(&xs->stimeout);
+
+ xs->status = cb->xfer->status;
+
+ if (cb->flags & CBF_SELTOUT)
+ xs->error = XS_SELTIMEOUT;
+ else if (cb->flags & CBF_TIMEOUT)
+ xs->error = XS_TIMEOUT;
+ else switch (xs->status) {
+ case SCSI_OK:
+ if (autosense == 0)
+ xs->error = XS_NOERROR;
+ else
+ xs->error = XS_SENSE;
+ break;
+
+ case SCSI_BUSY:
+ xs->error = XS_BUSY;
+ break;
+ case SCSI_CHECK:
+ if (autosense == 0)
+ cb->flags |= CBF_AUTOSENSE;
+ else
+ xs->error = XS_DRIVER_STUFFUP;
+ break;
+ case SCSI_OOSIOP_NOSTATUS:
+ /* the status byte was not updated, cmd was aborted. */
+ xs->error = XS_SELTIMEOUT;
+ break;
+
+ default:
+ xs->error = XS_RESET;
+ break;
+ }
+
+ if ((cb->flags & CBF_AUTOSENSE) == 0) {
+ /* Put it on the free list. */
+FREE:
+ TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain);
+ xs->resid = 0;
+ xs->flags |= ITSDONE;
+ scsi_done(xs);
+ } else {
+ /* Set up REQUEST_SENSE command */
+ struct scsi_sense *cmd =
+ (struct scsi_sense *)&cb->xfer->scsi_cmd;
+ int err;
+
+ bzero(cmd, sizeof(*cmd));
+ cmd->opcode = REQUEST_SENSE;
+ cmd->byte2 = xs->sc_link->lun << 5;
+ cmd->length = sizeof(xs->sense);
+
+ /* Sotup DMA map for data buffer */
+ cb->xsflags &= SCSI_POLL | SCSI_NOSLEEP;
+ cb->xsflags |= SCSI_DATA_IN;
+ cb->datalen = sizeof xs->sense;
+
+ err = bus_dmamap_load(sc->sc_dmat, cb->datadma,
+ &xs->sense, sizeof(xs->sense), NULL,
+ BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_READ);
+ if (err) {
+ printf("%s: unable to load REQUEST_SENSE data DMA map: %d",
+ sc->sc_dev.dv_xname, err);
+ xs->error = XS_DRIVER_STUFFUP;
+ goto FREE;
+ }
+ bus_dmamap_sync(sc->sc_dmat, cb->datadma,
+ 0, sizeof(xs->sense), BUS_DMASYNC_PREREAD);
+
+ TAILQ_INSERT_HEAD(&sc->sc_cbq, cb, chain);
+ if ((cb->xs->flags & SCSI_POLL) == 0) {
+ /* start expire timer */
+ timeout_add(&xs->stimeout, (xs->timeout / 1000) * hz);
+ }
+ }
+}
+
+void
+oosiop_timeout(void *arg)
+{
+ struct oosiop_cb *cb = arg;
+ struct scsi_xfer *xs = cb->xs;
+ struct oosiop_softc *sc = xs->sc_link->adapter_softc;
+ int s;
+
+ sc_print_addr(xs->sc_link);
+ printf("command 0x%02x timeout on xs %p\n", xs->cmd->opcode, xs);
+
+ s = splbio();
+
+ cb->flags |= CBF_TIMEOUT;
+ oosiop_done(sc, cb);
+
+ splx(s);
+}
+
+void
+oosiop_reset(struct oosiop_softc *sc)
+{
+ int i, s;
+
+ s = splbio();
+
+ /* Stop SCRIPTS processor */
+ oosiop_write_1(sc, OOSIOP_ISTAT, OOSIOP_ISTAT_ABRT);
+ delay(100);
+ oosiop_write_1(sc, OOSIOP_ISTAT, 0);
+
+ /* Reset the chip */
+ oosiop_write_1(sc, OOSIOP_DCNTL, sc->sc_dcntl | OOSIOP_DCNTL_RST);
+ delay(100);
+ oosiop_write_1(sc, OOSIOP_DCNTL, sc->sc_dcntl);
+ delay(10000);
+
+ /* Set up various chip parameters */
+ oosiop_write_1(sc, OOSIOP_SCNTL0, OOSIOP_ARB_FULL | OOSIOP_SCNTL0_EPG);
+ oosiop_write_1(sc, OOSIOP_SCNTL1, OOSIOP_SCNTL1_ESR);
+ oosiop_write_1(sc, OOSIOP_DCNTL, sc->sc_dcntl);
+ oosiop_write_1(sc, OOSIOP_DMODE, OOSIOP_DMODE_BL_8);
+ oosiop_write_1(sc, OOSIOP_SCID, OOSIOP_SCID_VALUE(sc->sc_id));
+ oosiop_write_1(sc, OOSIOP_DWT, 0xff); /* Enable DMA timeout */
+ oosiop_write_1(sc, OOSIOP_CTEST7, 0);
+ oosiop_write_1(sc, OOSIOP_SXFER, 0);
+
+ /* Clear all interrupts */
+ (void)oosiop_read_1(sc, OOSIOP_SSTAT0);
+ (void)oosiop_read_1(sc, OOSIOP_SSTAT1);
+ (void)oosiop_read_1(sc, OOSIOP_DSTAT);
+
+ /* Enable interrupts */
+ oosiop_write_1(sc, OOSIOP_SIEN,
+ OOSIOP_SIEN_M_A | OOSIOP_SIEN_STO | OOSIOP_SIEN_SGE |
+ OOSIOP_SIEN_UDC | OOSIOP_SIEN_RST | OOSIOP_SIEN_PAR);
+ oosiop_write_1(sc, OOSIOP_DIEN,
+ OOSIOP_DIEN_ABRT | OOSIOP_DIEN_SSI | OOSIOP_DIEN_SIR |
+ OOSIOP_DIEN_WTD | OOSIOP_DIEN_IID);
+
+ /* Set target state to asynchronous */
+ for (i = 0; i < OOSIOP_NTGT; i++) {
+ sc->sc_tgt[i].flags = 0;
+ sc->sc_tgt[i].scf = 0;
+ sc->sc_tgt[i].sxfer = 0;
+ }
+
+ splx(s);
+}
+
+void
+oosiop_reset_bus(struct oosiop_softc *sc)
+{
+ int s, i;
+
+ s = splbio();
+
+ /* Assert SCSI RST */
+ oosiop_write_1(sc, OOSIOP_SCNTL1, OOSIOP_SCNTL1_RST);
+ delay(25); /* Reset hold time (25us) */
+ oosiop_write_1(sc, OOSIOP_SCNTL1, 0);
+
+ /* Remove all nexuses */
+ for (i = 0; i < OOSIOP_NTGT; i++) {
+ if (sc->sc_tgt[i].nexus) {
+ sc->sc_tgt[i].nexus->xfer->status =
+ SCSI_OOSIOP_NOSTATUS; /* XXX */
+ oosiop_done(sc, sc->sc_tgt[i].nexus);
+ }
+ }
+
+ sc->sc_curcb = NULL;
+
+ delay(250000); /* Reset to selection (250ms) */
+
+ splx(s);
+}
+
+/*
+ * interrupt handler
+ */
+int
+oosiop_intr(struct oosiop_softc *sc)
+{
+ struct oosiop_cb *cb;
+ u_int32_t dcmd;
+ u_int8_t istat, dstat, sstat0;
+
+ istat = oosiop_read_1(sc, OOSIOP_ISTAT);
+
+ if ((istat & (OOSIOP_ISTAT_SIP | OOSIOP_ISTAT_DIP)) == 0)
+ return (0);
+
+ sc->sc_nextdsp = Ent_wait_reselect;
+
+ /* DMA interrupts */
+ if (istat & OOSIOP_ISTAT_DIP) {
+ oosiop_write_1(sc, OOSIOP_ISTAT, 0);
+
+ dstat = oosiop_read_1(sc, OOSIOP_DSTAT);
+
+ if (dstat & OOSIOP_DSTAT_ABRT) {
+ sc->sc_nextdsp = oosiop_read_4(sc, OOSIOP_DSP) -
+ sc->sc_scrbase - 8;
+
+ if (sc->sc_nextdsp == Ent_p_resel_msgin_move &&
+ (oosiop_read_1(sc, OOSIOP_SBCL) & OOSIOP_ACK)) {
+ if ((dstat & OOSIOP_DSTAT_DFE) == 0)
+ oosiop_flush_fifo(sc);
+ sc->sc_nextdsp += 8;
+ }
+ }
+
+ if (dstat & OOSIOP_DSTAT_SSI) {
+ sc->sc_nextdsp = oosiop_read_4(sc, OOSIOP_DSP) -
+ sc->sc_scrbase;
+ printf("%s: single step %08x\n", sc->sc_dev.dv_xname,
+ sc->sc_nextdsp);
+ }
+
+ if (dstat & OOSIOP_DSTAT_SIR) {
+ if ((dstat & OOSIOP_DSTAT_DFE) == 0)
+ oosiop_flush_fifo(sc);
+ oosiop_scriptintr(sc);
+ }
+
+ if (dstat & OOSIOP_DSTAT_WTD) {
+ printf("%s: DMA time out\n", sc->sc_dev.dv_xname);
+ oosiop_reset(sc);
+ }
+
+ if (dstat & OOSIOP_DSTAT_IID) {
+ dcmd = oosiop_read_4(sc, OOSIOP_DBC);
+ if ((dcmd & 0xf8000000) == 0x48000000) {
+ printf("%s: REQ asserted on WAIT DISCONNECT\n",
+ sc->sc_dev.dv_xname);
+ sc->sc_nextdsp = Ent_phasedispatch; /* XXX */
+ } else {
+ printf("%s: invalid SCRIPTS instruction "
+ "addr=%08x dcmd=%08x dsps=%08x\n",
+ sc->sc_dev.dv_xname,
+ oosiop_read_4(sc, OOSIOP_DSP) - 8, dcmd,
+ oosiop_read_4(sc, OOSIOP_DSPS));
+ oosiop_reset(sc);
+ OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_POSTWRITE);
+ oosiop_load_script(sc);
+ }
+ }
+
+ if ((dstat & OOSIOP_DSTAT_DFE) == 0)
+ oosiop_clear_fifo(sc);
+ }
+
+ /* SCSI interrupts */
+ if (istat & OOSIOP_ISTAT_SIP) {
+ if (istat & OOSIOP_ISTAT_DIP)
+ delay(1);
+ sstat0 = oosiop_read_1(sc, OOSIOP_SSTAT0);
+
+ if (sstat0 & OOSIOP_SSTAT0_M_A) {
+ /* SCSI phase mismatch during MOVE operation */
+ oosiop_phasemismatch(sc);
+ sc->sc_nextdsp = Ent_phasedispatch;
+ }
+
+ if (sstat0 & OOSIOP_SSTAT0_STO) {
+ if (sc->sc_curcb) {
+ sc->sc_curcb->flags |= CBF_SELTOUT;
+ oosiop_done(sc, sc->sc_curcb);
+ }
+ }
+
+ if (sstat0 & OOSIOP_SSTAT0_SGE) {
+ printf("%s: SCSI gross error\n", sc->sc_dev.dv_xname);
+ oosiop_reset(sc);
+ }
+
+ if (sstat0 & OOSIOP_SSTAT0_UDC) {
+ /* XXX */
+ if (sc->sc_curcb) {
+ printf("%s: unexpected disconnect\n",
+ sc->sc_dev.dv_xname);
+ oosiop_done(sc, sc->sc_curcb);
+ }
+ }
+
+ if (sstat0 & OOSIOP_SSTAT0_RST)
+ oosiop_reset(sc);
+
+ if (sstat0 & OOSIOP_SSTAT0_PAR)
+ printf("%s: parity error\n", sc->sc_dev.dv_xname);
+ }
+
+ /* Start next command if available */
+ if (sc->sc_nextdsp == Ent_wait_reselect && TAILQ_FIRST(&sc->sc_cbq)) {
+ cb = sc->sc_curcb = TAILQ_FIRST(&sc->sc_cbq);
+ TAILQ_REMOVE(&sc->sc_cbq, cb, chain);
+ sc->sc_tgt[cb->id].nexus = cb;
+
+ oosiop_setup_dma(sc);
+ oosiop_setup_syncxfer(sc);
+ sc->sc_lastcb = cb;
+ sc->sc_nextdsp = Ent_start_select;
+
+ /* Schedule timeout */
+ if ((cb->xs->flags & SCSI_POLL) == 0) {
+ /* start expire timer */
+ timeout_add(&cb->xs->stimeout,
+ (cb->xs->timeout / 1000) * hz);
+ }
+ }
+
+ sc->sc_active = (sc->sc_nextdsp != Ent_wait_reselect);
+
+ /* Restart script */
+ oosiop_write_4(sc, OOSIOP_DSP, sc->sc_nextdsp + sc->sc_scrbase);
+
+ return (1);
+}
+
+void
+oosiop_scriptintr(struct oosiop_softc *sc)
+{
+ struct oosiop_cb *cb;
+ u_int32_t icode;
+ u_int32_t dsp;
+ int i;
+ u_int8_t sfbr, resid, resmsg;
+
+ cb = sc->sc_curcb;
+ icode = oosiop_read_4(sc, OOSIOP_DSPS);
+
+ switch (icode) {
+ case A_int_done:
+ if (cb)
+ oosiop_done(sc, cb);
+ break;
+
+ case A_int_msgin:
+ if (cb)
+ oosiop_msgin(sc, cb);
+ break;
+
+ case A_int_extmsg:
+ /* extended message in DMA setup request */
+ sfbr = oosiop_read_1(sc, OOSIOP_SFBR);
+ OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_POSTWRITE);
+ oosiop_fixup_move(sc, Ent_p_extmsgin_move, sfbr,
+ cb->xferdma->dm_segs[0].ds_addr +
+ offsetof(struct oosiop_xfer, msgin[2]));
+ OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_PREWRITE);
+ sc->sc_nextdsp = Ent_rcv_extmsg;
+ break;
+
+ case A_int_resel:
+ /* reselected */
+ resid = oosiop_read_1(sc, OOSIOP_SFBR);
+ for (i = 0; i < OOSIOP_NTGT; i++)
+ if (resid & (1 << i))
+ break;
+ if (i == OOSIOP_NTGT) {
+ printf("%s: missing reselection target id\n",
+ sc->sc_dev.dv_xname);
+ break;
+ }
+ sc->sc_resid = i;
+ sc->sc_nextdsp = Ent_wait_resel_identify;
+
+ if (cb) {
+ /* Current command was lost arbitration */
+ sc->sc_tgt[cb->id].nexus = NULL;
+ TAILQ_INSERT_HEAD(&sc->sc_cbq, cb, chain);
+ sc->sc_curcb = NULL;
+ }
+
+ break;
+
+ case A_int_res_id:
+ cb = sc->sc_tgt[sc->sc_resid].nexus;
+ resmsg = oosiop_read_1(sc, OOSIOP_SFBR);
+ if (MSG_ISIDENTIFY(resmsg) && cb &&
+ (resmsg & MSG_IDENTIFY_LUNMASK) == cb->lun) {
+ sc->sc_curcb = cb;
+ if (cb != sc->sc_lastcb) {
+ oosiop_setup_dma(sc);
+ oosiop_setup_syncxfer(sc);
+ sc->sc_lastcb = cb;
+ }
+ if (cb->curdp != cb->savedp) {
+ cb->curdp = cb->savedp;
+ oosiop_setup_sgdma(sc, cb);
+ }
+ sc->sc_nextdsp = Ent_ack_msgin;
+ } else {
+ /* Reselection from invalid target */
+ oosiop_reset_bus(sc);
+ }
+ break;
+
+ case A_int_resfail:
+ /* reselect failed */
+ break;
+
+ case A_int_disc:
+ /* disconnected */
+ sc->sc_curcb = NULL;
+ break;
+
+ case A_int_err:
+ /* generic error */
+ dsp = oosiop_read_4(sc, OOSIOP_DSP);
+ printf("%s: script error at 0x%08x\n", sc->sc_dev.dv_xname,
+ dsp - 8);
+ sc->sc_curcb = NULL;
+ break;
+
+ case DATAIN_TRAP:
+ printf("%s: unexpected datain\n", sc->sc_dev.dv_xname);
+ /* XXX: need to reset? */
+ break;
+
+ case DATAOUT_TRAP:
+ printf("%s: unexpected dataout\n", sc->sc_dev.dv_xname);
+ /* XXX: need to reset? */
+ break;
+
+ default:
+ printf("%s: unknown intr code %08x\n", sc->sc_dev.dv_xname,
+ icode);
+ break;
+ }
+}
+
+void
+oosiop_msgin(struct oosiop_softc *sc, struct oosiop_cb *cb)
+{
+ struct oosiop_xfer *xfer;
+ int msgout;
+
+ xfer = cb->xfer;
+ sc->sc_nextdsp = Ent_ack_msgin;
+ msgout = 0;
+
+ OOSIOP_XFERMSG_SYNC(sc, cb,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ switch (xfer->msgin[0]) {
+ case MSG_EXTENDED:
+ switch (xfer->msgin[2]) {
+ case MSG_EXT_SDTR:
+ if (sc->sc_tgt[cb->id].flags & TGTF_WAITSDTR) {
+ /* Host initiated SDTR */
+ sc->sc_tgt[cb->id].flags &= ~TGTF_WAITSDTR;
+ } else {
+ /* Target initiated SDTR */
+ if (xfer->msgin[3] < sc->sc_minperiod)
+ xfer->msgin[3] = sc->sc_minperiod;
+ if (xfer->msgin[4] > OOSIOP_MAX_OFFSET)
+ xfer->msgin[4] = OOSIOP_MAX_OFFSET;
+ xfer->msgout[0] = MSG_EXTENDED;
+ xfer->msgout[1] = MSG_EXT_SDTR_LEN;
+ xfer->msgout[2] = MSG_EXT_SDTR;
+ xfer->msgout[3] = xfer->msgin[3];
+ xfer->msgout[4] = xfer->msgin[4];
+ cb->msgoutlen = 5;
+ msgout = 1;
+ }
+ oosiop_set_syncparam(sc, cb->id, (int)xfer->msgin[3],
+ (int)xfer->msgin[4]);
+ oosiop_setup_syncxfer(sc);
+ break;
+
+ default:
+ /* Reject message */
+ xfer->msgout[0] = MSG_MESSAGE_REJECT;
+ cb->msgoutlen = 1;
+ msgout = 1;
+ break;
+ }
+ break;
+
+ case MSG_SAVEDATAPOINTER:
+ cb->savedp = cb->curdp;
+ break;
+
+ case MSG_RESTOREPOINTERS:
+ if (cb->curdp != cb->savedp) {
+ cb->curdp = cb->savedp;
+ oosiop_setup_sgdma(sc, cb);
+ }
+ break;
+
+ case MSG_MESSAGE_REJECT:
+ if (sc->sc_tgt[cb->id].flags & TGTF_WAITSDTR) {
+ /* SDTR rejected */
+ sc->sc_tgt[cb->id].flags &= ~TGTF_WAITSDTR;
+ oosiop_set_syncparam(sc, cb->id, 0, 0);
+ oosiop_setup_syncxfer(sc);
+ }
+ break;
+
+ default:
+ /* Reject message */
+ xfer->msgout[0] = MSG_MESSAGE_REJECT;
+ cb->msgoutlen = 1;
+ msgout = 1;
+ }
+
+ OOSIOP_XFERMSG_SYNC(sc, cb,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ if (msgout) {
+ OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_POSTWRITE);
+ oosiop_fixup_move(sc, Ent_p_msgout_move, cb->msgoutlen,
+ cb->xferdma->dm_segs[0].ds_addr +
+ offsetof(struct oosiop_xfer, msgout[0]));
+ OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_PREWRITE);
+ sc->sc_nextdsp = Ent_sendmsg;
+ }
+}
diff --git a/sys/dev/ic/oosiopreg.h b/sys/dev/ic/oosiopreg.h
new file mode 100644
index 00000000000..f924a2f0877
--- /dev/null
+++ b/sys/dev/ic/oosiopreg.h
@@ -0,0 +1,324 @@
+/* $OpenBSD: oosiopreg.h,v 1.1 2004/03/12 00:04:57 miod Exp $ */
+/* $NetBSD: oosiopreg.h,v 1.3 2003/11/02 11:07:45 wiz Exp $ */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory.
+ *
+ * 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. 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.
+ *
+ * @(#)siopreg.h 7.3 (Berkeley) 2/5/91
+ */
+
+/*
+ * NCR 53C700 SCSI interface hardware description.
+ *
+ * From the Mach scsi driver for the 53C700 and amiga siop driver
+ */
+
+#define OOSIOP_SCNTL0 0x00 /* rw: SCSI control reg 0 */
+#define OOSIOP_SCNTL1 0x01 /* rw: SCSI control reg 1 */
+#define OOSIOP_SDID 0x02 /* rw: SCSI destination ID */
+#define OOSIOP_SIEN 0x03 /* rw: SCSI interrupt enable */
+#define OOSIOP_SCID 0x04 /* rw: SCSI Chip ID reg */
+#define OOSIOP_SXFER 0x05 /* rw: SCSI Transfer reg */
+#define OOSIOP_SODL 0x06 /* rw: SCSI Output Data Latch */
+#define OOSIOP_SOCL 0x07 /* rw: SCSI Output Control Latch */
+#define OOSIOP_SFBR 0x08 /* ro: SCSI First Byte Received */
+#define OOSIOP_SIDL 0x09 /* ro: SCSI Input Data Latch */
+#define OOSIOP_SBDL 0x0a /* ro: SCSI Bus Data Lines */
+#define OOSIOP_SBCL 0x0b /* rw: SCSI Bus Control Lines */
+#define OOSIOP_DSTAT 0x0c /* ro: DMA status */
+#define OOSIOP_SSTAT0 0x0d /* ro: SCSI status reg 0 */
+#define OOSIOP_SSTAT1 0x0e /* ro: SCSI status reg 1 */
+#define OOSIOP_SSTAT2 0x0f /* ro: SCSI status reg 2 */
+#define OOSIOP_SCRA0 0x10 /* rw: Scratch A */
+#define OOSIOP_SCRA1 0x11
+#define OOSIOP_SCRA2 0x12
+#define OOSIOP_SCRA3 0x13
+#define OOSIOP_CTEST0 0x14 /* ro: Chip test register 0 */
+#define OOSIOP_CTEST1 0x15 /* ro: Chip test register 1 */
+#define OOSIOP_CTEST2 0x16 /* ro: Chip test register 2 */
+#define OOSIOP_CTEST3 0x17 /* ro: Chip test register 3 */
+#define OOSIOP_CTEST4 0x18 /* rw: Chip test register 4 */
+#define OOSIOP_CTEST5 0x19 /* rw: Chip test register 5 */
+#define OOSIOP_CTEST6 0x1a /* rw: Chip test register 6 */
+#define OOSIOP_CTEST7 0x1b /* rw: Chip test register 7 */
+#define OOSIOP_TEMP 0x1c /* rw: Temporary Stack reg */
+#define OOSIOP_DFIFO 0x20 /* rw: DMA FIFO */
+#define OOSIOP_ISTAT 0x21 /* rw: Interrupt Status reg */
+#define OOSIOP_CTEST8 0x22 /* rw: Chip test register 8 */
+#define OOSIOP_CTEST9 0x23 /* ro: Chip test register 9 */
+#define OOSIOP_DBC 0x24 /* rw: DMA Byte Counter reg */
+#define OOSIOP_DCMD 0x27 /* rw: DMA Command Register */
+#define OOSIOP_DNAD 0x28 /* rw: DMA Next Address */
+#define OOSIOP_DSP 0x2c /* rw: DMA SCRIPTS Pointer reg */
+#define OOSIOP_DSPS 0x30 /* rw: DMA SCRIPTS Pointer Save reg */
+#define OOSIOP_DMODE 0x34 /* rw: DMA Mode reg */
+#define OOSIOP_RES35 0x35
+#define OOSIOP_RES36 0x36
+#define OOSIOP_RES37 0x37
+#define OOSIOP_RES38 0x38
+#define OOSIOP_DIEN 0x39 /* rw: DMA Interrupt Enable */
+#define OOSIOP_DWT 0x3a /* rw: DMA Watchdog Timer */
+#define OOSIOP_DCNTL 0x3b /* rw: DMA Control reg */
+#define OOSIOP_SCRB0 0x3c /* rw: Scratch B */
+#define OOSIOP_SCRB1 0x3d
+#define OOSIOP_SCRB2 0x3e
+#define OOSIOP_SCRB3 0x3f
+
+#define OOSIOP_NREGS 0x40
+
+
+/*
+ * Register defines
+ */
+
+/* Scsi control register 0 (scntl0) */
+
+#define OOSIOP_SCNTL0_ARB 0xc0 /* Arbitration mode */
+#define OOSIOP_ARB_SIMPLE 0x00
+#define OOSIOP_ARB_FULL 0xc0
+#define OOSIOP_SCNTL0_START 0x20 /* Start Sequence */
+#define OOSIOP_SCNTL0_WATN 0x10 /* (Select) With ATN */
+#define OOSIOP_SCNTL0_EPC 0x08 /* Enable Parity Checking */
+#define OOSIOP_SCNTL0_EPG 0x04 /* Enable Parity Generation */
+#define OOSIOP_SCNTL0_AAP 0x02 /* Assert ATN on Parity Error */
+#define OOSIOP_SCNTL0_TRG 0x01 /* Target Mode */
+
+/* Scsi control register 1 (scntl1) */
+
+#define OOSIOP_SCNTL1_EXC 0x80 /* Extra Clock Cycle of data setup */
+#define OOSIOP_SCNTL1_ADB 0x40 /* Assert Data Bus */
+#define OOSIOP_SCNTL1_ESR 0x20 /* Enable Selection/Reselection */
+#define OOSIOP_SCNTL1_CON 0x10 /* Connected */
+#define OOSIOP_SCNTL1_RST 0x08 /* Assert RST */
+#define OOSIOP_SCNTL1_AESP 0x04 /* Assert even SCSI parity */
+#define OOSIOP_SCNTL1_SND 0x02 /* Start Send operation */
+#define OOSIOP_SCNTL1_RCV 0x01 /* Start Receive operation */
+
+/* Scsi interrupt enable register (sien) */
+
+#define OOSIOP_SIEN_M_A 0x80 /* Phase Mismatch or ATN active */
+#define OOSIOP_SIEN_FC 0x40 /* Function Complete */
+#define OOSIOP_SIEN_STO 0x20 /* (Re)Selection timeout */
+#define OOSIOP_SIEN_SEL 0x10 /* (Re)Selected */
+#define OOSIOP_SIEN_SGE 0x08 /* SCSI Gross Error */
+#define OOSIOP_SIEN_UDC 0x04 /* Unexpected Disconnect */
+#define OOSIOP_SIEN_RST 0x02 /* RST asserted */
+#define OOSIOP_SIEN_PAR 0x01 /* Parity Error */
+
+/* Scsi chip ID (scid) */
+
+#define OOSIOP_SCID_VALUE(i) (1 << i)
+
+/* Scsi transfer register (sxfer) */
+
+#define OOSIOP_SXFER_DHP 0x80 /* Disable Halt on Parity error/
+ ATN asserted */
+#define OOSIOP_SXFER_TP 0x70 /* Synch Transfer Period */
+ /* see specs for formulas:
+ Period = TCP * (4 + XFERP )
+ TCP = 1 + CLK + 1..2;
+ */
+#define OOSIOP_SXFER_MO 0x0f /* Synch Max Offset */
+#define OOSIOP_MAX_OFFSET 8
+
+/* Scsi output data latch register (sodl) */
+
+/* Scsi output control latch register (socl) */
+
+#define OOSIOP_REQ 0x80 /* SCSI signal <x> asserted */
+#define OOSIOP_ACK 0x40
+#define OOSIOP_BSY 0x20
+#define OOSIOP_SEL 0x10
+#define OOSIOP_ATN 0x08
+#define OOSIOP_MSG 0x04
+#define OOSIOP_CD 0x02
+#define OOSIOP_IO 0x01
+
+#define OOSIOP_PHASE(socl) SCSI_PHASE(socl)
+
+/* Scsi first byte received register (sfbr) */
+
+/* Scsi input data latch register (sidl) */
+
+/* Scsi bus data lines register (sbdl) */
+
+/* Scsi bus control lines register (sbcl). Same as socl */
+
+#define OOSIOP_SBCL_SSCF1 0x02 /* wo */
+#define OOSIOP_SBCL_SSCF0 0x01 /* wo */
+
+/* DMA status register (dstat) */
+
+#define OOSIOP_DSTAT_DFE 0x80 /* DMA FIFO empty */
+#define OOSIOP_DSTAT_ABRT 0x10 /* Aborted */
+#define OOSIOP_DSTAT_SSI 0x08 /* SCRIPT Single Step */
+#define OOSIOP_DSTAT_SIR 0x04 /* SCRIPT Interrupt Instruction */
+#define OOSIOP_DSTAT_WTD 0x02 /* Watchdog Timeout Detected */
+#define OOSIOP_DSTAT_IID 0x01 /* Invalid Instruction Detected */
+
+/* Scsi status register 0 (sstat0) */
+
+#define OOSIOP_SSTAT0_M_A 0x80 /* Phase Mismatch or ATN active */
+#define OOSIOP_SSTAT0_FC 0x40 /* Function Complete */
+#define OOSIOP_SSTAT0_STO 0x20 /* (Re)Selection timeout */
+#define OOSIOP_SSTAT0_SEL 0x10 /* (Re)Selected */
+#define OOSIOP_SSTAT0_SGE 0x08 /* SCSI Gross Error */
+#define OOSIOP_SSTAT0_UDC 0x04 /* Unexpected Disconnect */
+#define OOSIOP_SSTAT0_RST 0x02 /* RST asserted */
+#define OOSIOP_SSTAT0_PAR 0x01 /* Parity Error */
+
+/* Scsi status register 1 (sstat1) */
+
+#define OOSIOP_SSTAT1_ILF 0x80 /* Input latch (sidl) full */
+#define OOSIOP_SSTAT1_ORF 0x40 /* output reg (sodr) full */
+#define OOSIOP_SSTAT1_OLF 0x20 /* output latch (sodl) full */
+#define OOSIOP_SSTAT1_AIP 0x10 /* Arbitration in progress */
+#define OOSIOP_SSTAT1_LOA 0x08 /* Lost arbitration */
+#define OOSIOP_SSTAT1_WOA 0x04 /* Won arbitration */
+#define OOSIOP_SSTAT1_RST 0x02 /* SCSI RST current value */
+#define OOSIOP_SSTAT1_SDP 0x01 /* SCSI SDP current value */
+
+/* Scsi status register 2 (sstat2) */
+
+#define OOSIOP_SSTAT2_FF 0xf0 /* SCSI FIFO flags (bytecount) */
+#define OOSIOP_SCSI_FIFO_DEEP 8
+#define OOSIOP_SSTAT2_SDP 0x08 /* Latched (on REQ) SCSI SDP */
+#define OOSIOP_SSTAT2_MSG 0x04 /* Latched SCSI phase */
+#define OOSIOP_SSTAT2_CD 0x02
+#define OOSIOP_SSTAT2_IO 0x01
+
+/* Chip test register 0 (ctest0) */
+
+#define OOSIOP_CTEST0_RTRG 0x02 /* Real Target Mode */
+#define OOSIOP_CTEST0_DDIR 0x01 /* Xfer direction (1-> from SCSI bus) */
+
+/* Chip test register 1 (ctest1) */
+
+#define OOSIOP_CTEST1_FMT 0xf0 /* Byte empty in DMA FIFO bottom
+ (high->byte3) */
+#define OOSIOP_CTEST1_FFL 0x0f /* Byte full in DMA FIFO top, same */
+
+/* Chip test register 2 (ctest2) */
+
+#define OOSIOP_CTEST2_SOFF 0x20 /* Synch Offset compare
+ (1-> zero Init, max Tgt) */
+#define OOSIOP_CTEST2_SFP 0x10 /* SCSI FIFO Parity */
+#define OOSIOP_CTEST2_DFP 0x08 /* DMA FIFO Parity */
+#define OOSIOP_CTEST2_TEOP 0x04 /* True EOP (a-la 5380) */
+#define OOSIOP_CTEST2_DREQ 0x02 /* DREQ status */
+#define OOSIOP_CTEST2_DACK 0x01 /* DACK status */
+
+/* Chip test register 3 (ctest3) read-only, top of SCSI FIFO */
+
+/* Chip test register 4 (ctest4) */
+
+#define OOSIOP_CTEST4_ZMOD 0x40 /* High-impedance outputs */
+#define OOSIOP_CTEST4_SZM 0x20 /* ditto, SCSI "outputs" */
+#define OOSIOP_CTEST4_SLBE 0x10 /* SCSI loopback enable */
+#define OOSIOP_CTEST4_SFWR 0x08 /* SCSI FIFO write enable (from sodl) */
+#define OOSIOP_CTEST4_FBL 0x07 /* DMA FIFO Byte Lane select
+ (from ctest6) 4->0, .. 7->3 */
+
+/* Chip test register 5 (ctest5) */
+
+#define OOSIOP_CTEST5_ADCK 0x80 /* Clock Address Incrementor */
+#define OOSIOP_CTEST5_BBCK 0x40 /* Clock Byte counter */
+#define OOSIOP_CTEST5_ROFF 0x20 /* Reset SCSI offset */
+#define OOSIOP_CTEST5_MASR 0x10 /* Master set/reset pulses
+ (of bits 3-0) */
+#define OOSIOP_CTEST5_DDIR 0x08 /* (re)set internal DMA direction */
+#define OOSIOP_CTEST5_EOP 0x04 /* (re)set internal EOP */
+#define OOSIOP_CTEST5_DREQ 0x02 /* (re)set internal REQ */
+#define OOSIOP_CTEST5_DACK 0x01 /* (re)set internal ACK */
+
+/* Chip test register 6 (ctest6) DMA FIFO access */
+
+/* Chip test register 7 (ctest7) */
+
+#define OOSIOP_CTEST7_STD 0x10 /* Selection timeout disable */
+#define OOSIOP_CTEST7_DFP 0x08 /* DMA FIFO parity bit */
+#define OOSIOP_CTEST7_EVP 0x04 /* Even parity (to host bus) */
+#define OOSIOP_CTEST7_DIFF 0x01 /* Differential mode */
+
+/* DMA FIFO register (dfifo) */
+
+#define OOSIOP_DFIFO_FLF 0x80 /* Flush (spill) DMA FIFO */
+#define OOSIOP_DFIFO_CLF 0x40 /* Clear DMA and SCSI FIFOs */
+#define OOSIOP_DFIFO_BO 0x3f /* FIFO byte offset counter */
+
+/* Interrupt status register (istat) */
+
+#define OOSIOP_ISTAT_ABRT 0x80 /* Abort operation */
+#define OOSIOP_ISTAT_CON 0x08 /* Connected */
+#define OOSIOP_ISTAT_PRE 0x04 /* Pointer register empty */
+#define OOSIOP_ISTAT_SIP 0x02 /* SCSI Interrupt pending */
+#define OOSIOP_ISTAT_DIP 0x01 /* DMA Interrupt pending */
+
+/* Chip test register 8 (ctest8) */
+
+/* DMA Byte Counter register (dbc) */
+#define OOSIOP_DBC_MAX 0x00ffffff
+
+/* DMA Mode register (dmode) */
+
+#define OOSIOP_DMODE_BL_MASK 0xc0 /* 0->1 1->2 2->4 3->8 */
+#define OOSIOP_DMODE_BL_1 0x00
+#define OOSIOP_DMODE_BL_2 0x40
+#define OOSIOP_DMODE_BL_4 0x80
+#define OOSIOP_DMODE_BL_8 0xc0
+#define OOSIOP_DMODE_BW16 0x20 /* Bus Width is 16 bits */
+#define OOSIOP_DMODE_286 0x10 /* 286 mode */
+#define OOSIOP_DMODE_IO_M 0x08 /* xfer data to memory or I/O space */
+#define OOSIOP_DMODE_FAM 0x04 /* fixed address mode */
+#define OOSIOP_DMODE_PIPE 0x02 /* SCRIPTS in Pipeline mode */
+#define OOSIOP_DMODE_MAN 0x01 /* SCRIPTS in Manual start mode */
+
+/* DMA interrupt enable register (dien) */
+
+#define OOSIOP_DIEN_BF 0x20 /* On Bus Fault */
+#define OOSIOP_DIEN_ABRT 0x10 /* On Abort */
+#define OOSIOP_DIEN_SSI 0x08 /* On SCRIPTS sstep */
+#define OOSIOP_DIEN_SIR 0x04 /* On SCRIPTS intr instruction */
+#define OOSIOP_DIEN_WTD 0x02 /* On watchdog timeout */
+#define OOSIOP_DIEN_IID 0x01 /* On illegal instruction detected */
+
+/* DMA control register (dcntl) */
+
+#define OOSIOP_DCNTL_CF_MASK 0xc0 /* Clock frequency dividers: */
+#define OOSIOP_DCNTL_CF_2 0x00 /* 0 --> 37.51..50.00 MHz, div=2 */
+#define OOSIOP_DCNTL_CF_1_5 0x40 /* 1 --> 25.01..37.50 MHz, div=1.5 */
+#define OOSIOP_DCNTL_CF_1 0x80 /* 2 --> 16.67..25.00 MHz, div=1 */
+#define OOSIOP_DCNTL_CF_3 0xc0 /* 3 --> 50.01..66.67 MHz, div=3 */
+#define OOSIOP_DCNTL_S16 0x20 /* SCRIPTS fetches 16bits at a time */
+#define OOSIOP_DCNTL_SSM 0x10 /* Single step mode */
+#define OOSIOP_DCNTL_LLM 0x08 /* Enable SCSI Low-level mode */
+#define OOSIOP_DCNTL_STD 0x04 /* Start DMA operation */
+#define OOSIOP_DCNTL_RST 0x01 /* Software reset */
diff --git a/sys/dev/ic/oosiopvar.h b/sys/dev/ic/oosiopvar.h
new file mode 100644
index 00000000000..e197773efb4
--- /dev/null
+++ b/sys/dev/ic/oosiopvar.h
@@ -0,0 +1,164 @@
+/* $OpenBSD: oosiopvar.h,v 1.1 2004/03/12 00:04:57 miod Exp $ */
+/* $NetBSD: oosiopvar.h,v 1.2 2003/05/03 18:11:23 wiz Exp $ */
+
+/*
+ * Copyright (c) 2001 Shuichiro URATA. 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. 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 OOSIOP_NTGT 8 /* Max targets */
+#define OOSIOP_NCB 32 /* Initial command buffers */
+#define OOSIOP_NSG (MIN(btoc(MAXPHYS) + 1, 32)) /* Max S/G operation */
+#define OOSIOP_MAX_XFER ctob(OOSIOP_NSG - 1)
+
+struct oosiop_xfer {
+ /* script for scatter/gather DMA (move*nsg+jump) */
+ u_int32_t datain_scr[(OOSIOP_NSG + 1) * 2];
+ u_int32_t dataout_scr[(OOSIOP_NSG + 1) * 2];
+
+ u_int8_t msgin[8];
+ u_int8_t msgout[8];
+ u_int8_t status;
+ u_int8_t pad[7];
+
+ struct scsi_generic scsi_cmd; /* DMA'able copy of xs->cmd */
+ u_int32_t pad2[1+4]; /* pad to 256 bytes */
+} __packed;
+
+#define SCSI_OOSIOP_NOSTATUS 0xff /* device didn't report status */
+
+#define OOSIOP_XFEROFF(x) offsetof(struct oosiop_xfer, x)
+#define OOSIOP_DINSCROFF OOSIOP_XFEROFF(datain_scr[0])
+#define OOSIOP_DOUTSCROFF OOSIOP_XFEROFF(dataout_scr[0])
+#define OOSIOP_MSGINOFF OOSIOP_XFEROFF(msgin[0])
+#define OOSIOP_MSGOUTOFF OOSIOP_XFEROFF(msgout[0])
+#define OOSIOP_CMDOFF OOSIOP_XFEROFF(scsi_cmd)
+
+#define OOSIOP_XFERSCR_SYNC(sc, cb, ops) \
+ bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_DINSCROFF, \
+ OOSIOP_MSGINOFF - OOSIOP_DINSCROFF, (ops))
+#define OOSIOP_DINSCR_SYNC(sc, cb, ops) \
+ bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_DINSCROFF, \
+ OOSIOP_DOUTSCROFF - OOSIOP_DINSCROFF, (ops))
+#define OOSIOP_DOUTSCR_SYNC(sc, cb, ops) \
+ bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_DOUTSCROFF,\
+ OOSIOP_MSGINOFF - OOSIOP_DOUTSCROFF, (ops))
+#define OOSIOP_XFERMSG_SYNC(sc, cb, ops) \
+ bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_MSGINOFF, \
+ sizeof(struct oosiop_xfer) - OOSIOP_MSGINOFF, (ops))
+
+#define OOSIOP_SCRIPT_SYNC(sc, ops) \
+ bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_scrdma, \
+ 0, sizeof(oosiop_script), (ops))
+
+struct oosiop_cb {
+ TAILQ_ENTRY(oosiop_cb) chain;
+
+ struct scsi_xfer *xs; /* SCSI xfer ctrl block from above */
+ int flags;
+ int id; /* target scsi id */
+ int lun; /* target lun */
+
+ bus_dmamap_t cmddma; /* DMA map for command out */
+ bus_dmamap_t datadma; /* DMA map for data I/O */
+ bus_dmamap_t xferdma; /* DMA map for xfer block */
+
+ int curdp; /* current data pointer */
+ int savedp; /* saved data pointer */
+ int msgoutlen;
+
+ int xsflags; /* copy of xs->flags */
+ int datalen; /* copy of xs->datalen */
+
+ struct oosiop_xfer *xfer; /* DMA xfer block */
+};
+
+/* oosiop_cb flags */
+#define CBF_SELTOUT 0x01 /* Selection timeout */
+#define CBF_TIMEOUT 0x02 /* Command timeout */
+#define CBF_AUTOSENSE 0x04 /* Request sense due to SCSI_CHECK */
+
+struct oosiop_target {
+ struct oosiop_cb *nexus;
+ int flags;
+ u_int8_t scf; /* synchronous clock divisor */
+ u_int8_t sxfer; /* synchronous period and offset */
+};
+
+/* target flags */
+#define TGTF_SYNCNEG 0x01 /* Trigger synchronous negotiation */
+#define TGTF_WAITSDTR 0x02 /* Waiting SDTR from target */
+
+struct oosiop_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t sc_bst; /* bus space tag */
+ bus_space_handle_t sc_bsh; /* bus space handle */
+
+ bus_dma_tag_t sc_dmat; /* bus DMA tag */
+ bus_dmamap_t sc_scrdma; /* script DMA map */
+
+ bus_addr_t sc_scrbase; /* script DMA base address */
+ u_int32_t *sc_scr; /* ptr to script memory */
+
+ int sc_chip; /* 700 or 700-66 */
+#define OOSIOP_700 0
+#define OOSIOP_700_66 1
+
+ int sc_id; /* SCSI ID of this interface */
+ int sc_freq; /* SCLK frequency */
+ int sc_ccf; /* asynchronous divisor (*10) */
+ u_int8_t sc_dcntl;
+ u_int8_t sc_minperiod;
+
+ struct oosiop_target sc_tgt[OOSIOP_NTGT];
+
+ struct scsi_link sc_link;
+
+ /* Lists of command blocks */
+ TAILQ_HEAD(oosiop_cb_queue, oosiop_cb) sc_free_cb,
+ sc_cbq;
+
+ struct oosiop_cb *sc_curcb; /* current command */
+ struct oosiop_cb *sc_lastcb; /* last activated command */
+
+ bus_addr_t sc_reselbuf; /* msgin buffer for reselection */
+ int sc_resid; /* reselected target id */
+
+ int sc_active;
+ int sc_nextdsp;
+};
+
+#define oosiop_read_1(sc, addr) \
+ bus_space_read_1((sc)->sc_bst, (sc)->sc_bsh, (addr))
+#define oosiop_write_1(sc, addr, data) \
+ bus_space_write_1((sc)->sc_bst, (sc)->sc_bsh, (addr), (data))
+/* XXX byte swapping should be handled by MD bus_space(9)? */
+#define oosiop_read_4(sc, addr) \
+ letoh32(bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (addr)))
+#define oosiop_write_4(sc, addr, data) \
+ bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (addr), htole32(data))
+
+void oosiop_attach(struct oosiop_softc *);
+int oosiop_intr(struct oosiop_softc *);
diff --git a/sys/dev/microcode/siop/Makefile b/sys/dev/microcode/siop/Makefile
index db8a569b205..223a767324a 100644
--- a/sys/dev/microcode/siop/Makefile
+++ b/sys/dev/microcode/siop/Makefile
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile,v 1.2 2003/01/08 02:11:38 krw Exp $
+# $OpenBSD: Makefile,v 1.3 2004/03/12 00:04:57 miod Exp $
# $NetBSD: Makefile,v 1.1 2000/04/21 17:57:01 bouyer Exp $
-all: siop.out osiop.out
+all: siop.out osiop.out oosiop.out
PROG= ncr53cxxx
MKSHARE=no
@@ -9,11 +9,14 @@ MAN=
.include <bsd.prog.mk>
-regen: siop.out osiop.out
-headers: siop.out osiop.out
+regen: siop.out osiop.out oosiop.out
+headers: siop.out osiop.out oosiop.out
siop.out: siop.ss ${PROG}
./${PROG} siop.ss -p siop.out
osiop.out: osiop.ss ${PROG}
./${PROG} osiop.ss -p osiop.out
+
+oosiop.out: oosiop.ss ${PROG}
+ ./${PROG} oosiop.ss -p oosiop.out
diff --git a/sys/dev/microcode/siop/ncr53cxxx.c b/sys/dev/microcode/siop/ncr53cxxx.c
index d742fdd6c80..12b6c0aa06f 100644
--- a/sys/dev/microcode/siop/ncr53cxxx.c
+++ b/sys/dev/microcode/siop/ncr53cxxx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ncr53cxxx.c,v 1.5 2003/06/27 20:38:49 krw Exp $ */
+/* $OpenBSD: ncr53cxxx.c,v 1.6 2004/03/12 00:04:57 miod Exp $ */
/* $NetBSD: ncr53cxxx.c,v 1.10 2002/04/21 22:40:10 bouyer Exp $ */
/*
@@ -415,7 +415,7 @@ main (int argc, char *argv[])
if (outfp) {
time_t cur_time;
- fprintf(outfp, "/*\t$NetBSD: ncr53cxxx.c,v 1.10 2002/04/21 22:40:10 bouyer Exp $\t*/\n");
+ fprintf(outfp, "/*\t$OpenBSD: ncr53cxxx.c,v 1.6 2004/03/12 00:04:57 miod Exp $\t*/\n");
fprintf(outfp, "/*\n");
fprintf(outfp, " *\tDO NOT EDIT - this file is automatically generated.\n");
time(&cur_time);
@@ -1046,10 +1046,12 @@ void f_wait (void)
errout ("Expected SELECT or RESELECT");
++i;
if (reserved ("rel", i)) {
+#if 0 /* XXX driver will fix relative dsps to absolute */
if (arch < ARCH710) {
errout ("Wrong arch for relative dsps");
return;
}
+#endif
i += 2;
inst1 = evaluate (i) - dsps - 8;
inst0 |= 0x04000000;
@@ -1157,10 +1159,12 @@ void transfer (int word0, int type)
i = tokenix;
inst0 = word0;
if (type == 0 && reserved ("rel", i)) {
+#if 0 /* XXX driver will fix relative dsps to absolute */
if (arch < ARCH710) {
errout ("Wrong arch for relative dsps");
return;
}
+#endif
inst1 = evaluate (i + 2) - dsps - 8;
i += 4;
inst0 |= 0x00800000;
@@ -1244,10 +1248,12 @@ void select_reselect (int t)
inst0 |= (evaluate (t++) & 0xff) << 16;
if (tokens[t++].type == ',') {
if (reserved ("rel", t)) {
+#if 0 /* XXX driver will fix relative dsps to absolute */
if (arch < ARCH710) {
errout ("Wrong arch for relative dsps");
return;
}
+#endif
inst0 |= 0x04000000;
inst1 = evaluate (t + 2) - dsps - 8;
}
diff --git a/sys/dev/microcode/siop/oosiop.ss b/sys/dev/microcode/siop/oosiop.ss
new file mode 100644
index 00000000000..b1c084f803c
--- /dev/null
+++ b/sys/dev/microcode/siop/oosiop.ss
@@ -0,0 +1,150 @@
+; $NetBSD: oosiop.ss,v 1.2 2003/04/06 09:48:42 tsutsui Exp $
+
+;
+; Copyright (c) 2001 Shuichiro URATA. 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. 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.
+;
+
+; NCR 53c700 script
+;
+
+ARCH 700
+
+; interrupt codes
+ABSOLUTE int_done = 0xbeef0000
+ABSOLUTE int_msgin = 0xbeef0001
+ABSOLUTE int_extmsg = 0xbeef0002
+ABSOLUTE int_resel = 0xbeef0003
+ABSOLUTE int_res_id = 0xbeef0004
+ABSOLUTE int_resfail = 0xbeef0005
+ABSOLUTE int_disc = 0xbeef0006
+ABSOLUTE int_err = 0xdeadbeef
+
+; patch entries
+ENTRY p_resel_msgin_move
+ENTRY p_select
+ENTRY p_datain_jump
+ENTRY p_dataout_jump
+ENTRY p_msgin_move
+ENTRY p_msgout_move
+ENTRY p_cmdout_move
+ENTRY p_status_move
+ENTRY p_extmsglen_move
+ENTRY p_extmsgin_move
+
+
+PROC oosiop_script:
+
+ENTRY wait_reselect
+wait_reselect:
+ WAIT RESELECT REL(reselect_fail)
+ INT int_resel
+reselect_fail:
+ INT int_resfail
+
+ENTRY wait_resel_identify
+wait_resel_identify:
+ INT int_err, WHEN NOT MSG_IN
+p_resel_msgin_move:
+ MOVE 0, 0, WHEN MSG_IN
+ INT int_res_id
+
+ENTRY start_select
+start_select:
+p_select:
+ SELECT ATN 0, REL(wait_reselect)
+
+ENTRY phasedispatch
+phasedispatch:
+ JUMP REL(msgin), WHEN MSG_IN
+ JUMP REL(msgout), WHEN MSG_OUT
+ JUMP REL(status), WHEN STATUS
+ JUMP REL(cmdout), WHEN CMD
+p_datain_jump:
+ JUMP 0, WHEN DATA_IN
+p_dataout_jump:
+ JUMP 0, WHEN DATA_OUT
+ INT int_err
+
+msgin:
+ CLEAR ATN
+p_msgin_move:
+ MOVE 0, 0, WHEN MSG_IN
+ JUMP REL(complete), IF 0x00
+ JUMP REL(extmsgsetup), IF 0x01
+ JUMP REL(disconnect), IF 0x04
+ INT int_msgin
+
+ENTRY ack_msgin
+ack_msgin:
+ CLEAR ACK
+ JUMP REL(phasedispatch)
+
+ENTRY sendmsg
+sendmsg:
+ SET ATN
+ CLEAR ACK
+msgout:
+p_msgout_move:
+ MOVE 0, 0, WHEN MSG_OUT
+ CLEAR ATN
+ JUMP REL(phasedispatch)
+
+cmdout:
+ CLEAR ATN
+p_cmdout_move:
+ MOVE 0, 0, WHEN CMD
+ JUMP REL(phasedispatch)
+
+status:
+p_status_move:
+ MOVE 0, 0, WHEN STATUS
+ JUMP REL(phasedispatch)
+
+disconnect:
+ CLEAR ACK
+ WAIT DISCONNECT
+ INT int_disc
+
+complete:
+ CLEAR ACK
+ WAIT DISCONNECT
+ INT int_done
+
+; receive extended message length
+extmsgsetup:
+ CLEAR ACK
+ INT int_err, IF NOT MSG_IN
+p_extmsglen_move:
+ MOVE 0, 0, WHEN MSG_IN
+ INT int_extmsg
+
+; receive extended message
+ENTRY rcv_extmsg
+rcv_extmsg:
+ CLEAR ACK
+ INT int_err, IF NOT MSG_IN
+p_extmsgin_move:
+ MOVE 0, 0, WHEN MSG_IN
+ INT int_msgin