Subject: si driver -- here it is.
To: None <port-sparc@NetBSD.ORG>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: port-sparc
Date: 06/18/1995 22:14:07
Attached below is the `si' driver I'm currently using on my 4/260.  It's 
basically the Sun 3 `si' driver with tweaks.

The config file line should look like:

si0     at vmes0 addr 0xff200000 level 2 vect 0x40

...and the files.sparc lines:

device si at vmes: scsi
file    arch/sparc/dev/si.c             si needs-flag

Note that I've only tested this with 2 ESDI disks behind an Emulex MD21, 
but if it works with that old thing, I'd think it'll work with modern 
disks as well :-)

I'm aware that this driver has the shortcomings (read: no DMA) of the Sun 
3 driver; no doubt someone will remind me of that fact, but my priority 
was to make _something_ work, so...

Have fun.

--------------------------------------------------------------------------
Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                               Home: 408.866.1912
NAS: M/S 258-6                                          Work: 415.604.0935
Moffet Field, CA 94035                                 Pager: 415.428.6939

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	ncr5380.h
#	si.c
#	sidefs.h
#	sireg.h
#
echo x - ncr5380.h
sed 's/^X//' >ncr5380.h << 'END-of-ncr5380.h'
X/*	$NetBSD: scsi_5380.h,v 1.4 1994/11/21 21:31:18 gwr Exp $	*/
X
X/* 
X * Mach Operating System
X * Copyright (c) 1991,1990,1989 Carnegie Mellon University
X * All Rights Reserved.
X * 
X * Permission to use, copy, modify and distribute this software and its
X * documentation is hereby granted, provided that both the copyright
X * notice and this permission notice appear in all copies of the
X * software, derivative works or modified versions, and any portions
X * thereof, and that both notices appear in supporting documentation.
X * 
X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 
X * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
X * 
X * Carnegie Mellon requests users of this software to return to
X * 
X *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
X *  School of Computer Science
X *  Carnegie Mellon University
X *  Pittsburgh PA 15213-3890
X * 
X * any improvements or extensions that they make and grant Carnegie the
X * rights to redistribute these changes.
X */
X/*
X * HISTORY (mach3)
X * Revision 2.3  91/08/24  12:25:10  af
X * 	Moved padding of regmap in impl file.
X * 	[91/08/02  04:22:39  af]
X * 
X * Revision 2.2  91/06/19  16:28:35  rvb
X * 	From the NCR data sheets
X * 	"NCR 5380 Family, SCSI Protocol Controller Data Manual"
X * 	NCR Microelectronics Division, Colorado Spring, 6/98 T01891L
X * 	[91/04/21            af]
X * 
X */
X
X/*
X *	File: scsi_5380.h
X * 	Author: Alessandro Forin, Carnegie Mellon University
X *	Date:	5/91
X *
X *	Defines for the NCR 5380 (SCSI chip), aka Am5380
X */
X
X/*
X * Register map
X */
X
Xtypedef struct {
X	volatile unsigned char	sci_data;	/* r:  Current data */
X#define			sci_odata sci_data	/* w:  Out data */
X	volatile unsigned char	sci_icmd;	/* rw: Initiator command */
X	volatile unsigned char	sci_mode;	/* rw: Mode */
X	volatile unsigned char	sci_tcmd;	/* rw: Target command */
X	volatile unsigned char	sci_bus_csr;	/* r:  Bus Status */
X#define			sci_sel_enb sci_bus_csr	/* w:  Select enable */
X	volatile unsigned char	sci_csr;	/* r:  Status */
X#define			sci_dma_send sci_csr	/* w:  Start dma send data */
X	volatile unsigned char	sci_idata;	/* r:  Input data */
X#define			sci_trecv sci_idata	/* w:  Start dma receive, target */
X	volatile unsigned char	sci_iack;	/* r:  Interrupt Acknowledge  */
X#define			sci_irecv sci_iack	/* w:  Start dma receive, initiator */
X} sci_regmap_t;
X
X
X/*
X * Initiator command register
X */
X
X#define SCI_ICMD_DATA		0x01		/* rw: Assert data bus   */
X#define SCI_ICMD_ATN		0x02		/* rw: Assert ATN signal */
X#define SCI_ICMD_SEL		0x04		/* rw: Assert SEL signal */
X#define SCI_ICMD_BSY		0x08		/* rw: Assert BSY signal */
X#define SCI_ICMD_ACK		0x10		/* rw: Assert ACK signal */
X#define SCI_ICMD_LST		0x20		/* r:  Lost arbitration */
X#define SCI_ICMD_DIFF	SCI_ICMD_LST		/* w:  Differential cable */
X#define SCI_ICMD_AIP		0x40		/* r:  Arbitration in progress */
X#define SCI_ICMD_TEST	SCI_ICMD_AIP		/* w:  Test mode */
X#define SCI_ICMD_RST		0x80		/* rw: Assert RST signal */
X
X
X/*
X * Mode register
X */
X
X#define SCI_MODE_ARB		0x01		/* rw: Start arbitration */
X#define SCI_MODE_DMA		0x02		/* rw: Enable DMA xfers */
X#define SCI_MODE_MONBSY		0x04		/* rw: Monitor BSY signal */
X#define SCI_MODE_DMA_IE		0x08		/* rw: Enable DMA complete interrupt */
X#define SCI_MODE_PERR_IE	0x10		/* rw: Interrupt on parity errors */
X#define SCI_MODE_PAR_CHK	0x20		/* rw: Check parity */
X#define SCI_MODE_TARGET		0x40		/* rw: Target mode (Initiator if 0) */
X#define SCI_MODE_BLOCKDMA	0x80		/* rw: Block-mode DMA handshake (MBZ) */
X
X
X/*
X * Target command register
X */
X
X#define SCI_TCMD_IO		0x01		/* rw: Assert I/O signal */
X#define SCI_TCMD_CD		0x02		/* rw: Assert C/D signal */
X#define SCI_TCMD_MSG		0x04		/* rw: Assert MSG signal */
X#define SCI_TCMD_PHASE_MASK	0x07		/* r:  Mask for current bus phase */
X#define SCI_TCMD_REQ		0x08		/* rw: Assert REQ signal */
X#define	SCI_TCMD_LAST_SENT	0x80		/* ro: Last byte was xferred
X						 *     (not on 5380/1) */
X
X#define	SCI_PHASE(x)		SCSI_PHASE(x)
X
X/*
X * Current (SCSI) Bus status
X */
X
X#define SCI_BUS_DBP		0x01		/* r:  Data Bus parity */
X#define SCI_BUS_SEL		0x02		/* r:  SEL signal */
X#define SCI_BUS_IO		0x04		/* r:  I/O signal */
X#define SCI_BUS_CD		0x08		/* r:  C/D signal */
X#define SCI_BUS_MSG		0x10		/* r:  MSG signal */
X#define SCI_BUS_REQ		0x20		/* r:  REQ signal */
X#define SCI_BUS_BSY		0x40		/* r:  BSY signal */
X#define SCI_BUS_RST		0x80		/* r:  RST signal */
X
X#define	SCI_CUR_PHASE(x)	SCSI_PHASE((x)>>2)
X
X/*
X * Bus and Status register
X */
X
X#define SCI_CSR_ACK		0x01		/* r:  ACK signal */
X#define SCI_CSR_ATN		0x02		/* r:  ATN signal */
X#define SCI_CSR_DISC		0x04		/* r:  Disconnected (BSY==0) */
X#define SCI_CSR_PHASE_MATCH	0x08		/* r:  Bus and SCI_TCMD match */
X#define SCI_CSR_INT		0x10		/* r:  Interrupt request */
X#define SCI_CSR_PERR		0x20		/* r:  Parity error */
X#define SCI_CSR_DREQ		0x40		/* r:  DMA request */
X#define SCI_CSR_DONE		0x80		/* r:  DMA count is zero */
X
END-of-ncr5380.h
echo x - si.c
sed 's/^X//' >si.c << 'END-of-si.c'
X/*	$NetBSD: si.c,v 1.17 1995/06/01 20:22:36 gwr Exp $	*/
X
X/*
X * Copyright (C) 1994 Adam Glass, Gordon W. Ross
X * Copyright (C) 1993	Allen K. Briggs, Chris P. Caputo,
X *			Michael L. Finch, Bradley A. Grantham, and
X *			Lawrence A. Kesteloot
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X *    must display the following acknowledgement:
X *	This product includes software developed by the Alice Group.
X * 4. The names of the Alice Group or any of its members may not be used
X *    to endorse or promote products derived from this software without
X *    specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
X * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
X * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
X/*
X * NOTE: This is 99% Sun 3 `si' driver.  I've made the probe and attach
X * routines a little minimalistic, and adjusted them slightly for the Sun 4.
X * Also, fixed some logic in si_select_target().
X *	Jason R. Thorpe <thorpej@nas.nasa.gov>
X */
X
X#define DEBUG 1
X
X/* XXX - Need to add support for real DMA. -gwr */
X/* #define PSEUDO_DMA 1 (broken) */
X
X#include <sys/types.h>
X#include <sys/malloc.h>
X#include <sys/param.h>
X#include <sys/systm.h>
X#include <sys/errno.h>
X#include <sys/buf.h>
X#include <sys/proc.h>
X#include <sys/user.h>
X#include <sys/device.h>
X
X#include <machine/autoconf.h>
X#include <machine/cpu.h>
X#include <machine/pmap.h>
X
X#include <scsi/scsi_all.h>
X#include <scsi/scsi_debug.h>
X#include <scsi/scsiconf.h>
X
X#include <sparc/dev/ncr5380.h>
X#include <sparc/dev/sireg.h>
X#include <sparc/dev/sidefs.h>
X
X#ifdef	DEBUG
Xstatic int si_debug = 0;
Xstatic int si_flags = 0 /* | SDEV_DB2 */ ;
X#endif
X
X#define SCI_PHASE_DISC		0	/* sort of ... */
X#define SCI_CLR_INTR(regs)	((volatile)(regs->sci_iack))
X#define SCI_ACK(ptr,phase)	(ptr)->sci_tcmd = (phase)
X#define SCSI_TIMEOUT_VAL	1000000
X#define WAIT_FOR_NOT_REQ(ptr) {	\
X	int scsi_timeout = SCSI_TIMEOUT_VAL; \
X	while ( ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
X		 ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
X		 ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
X		 (--scsi_timeout) ); \
X	if (!scsi_timeout) { \
X		printf("scsi timeout--WAIT_FOR_NOT_REQ---%s, line %d.\n", \
X			__FILE__, __LINE__); \
X		goto scsi_timeout_error; \
X	} \
X	}
X#define WAIT_FOR_REQ(ptr) {	\
X	int scsi_timeout = SCSI_TIMEOUT_VAL; \
X	while ( (((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
X		(((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
X		(((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
X		 (--scsi_timeout) ); \
X	if (!scsi_timeout) { \
X		printf("scsi timeout--WAIT_FOR_REQ---%s, line %d.\n", \
X			__FILE__, __LINE__); \
X		goto scsi_timeout_error; \
X	} \
X	}
X#define WAIT_FOR_BSY(ptr) {	\
X	int scsi_timeout = SCSI_TIMEOUT_VAL; \
X	while ( (((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
X		(((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
X		(((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
X		 (--scsi_timeout) ); \
X	if (!scsi_timeout) { \
X		printf("scsi timeout--WAIT_FOR_BSY---%s, line %d.\n", \
X			__FILE__, __LINE__); \
X		goto scsi_timeout_error; \
X	} \
X	}
X
X#define ARBITRATION_RETRIES 1000
X
X#ifdef DDB
Xint Debugger();
X#else
X#define Debugger() panic("Should call Debugger here %s:%d", \
X			 __FILE__, __LINE__)
X#endif
X
Xstruct ncr5380_softc {
X    struct device sc_dev;
X    struct intrhand sc_ih;	/* interrupt info */
X    volatile void *sc_regs;
X    int sc_adapter_type;
X    int sc_adapter_iv_am;	/* int. vec + address modifier */
X    struct scsi_link sc_link;
X};
X
Xstatic void		ncr5380_minphys(struct buf *bp);
Xstatic int		ncr5380_scsi_cmd(struct scsi_xfer *xs);
Xstatic int		ncr5380_reset_adapter(struct ncr5380_softc *);
Xstatic int		ncr5380_reset_scsibus(struct ncr5380_softc *);
Xstatic int		ncr5380_poll(int adapter, int timeout);
Xstatic int		ncr5380_send_cmd(struct scsi_xfer *xs);
X
Xstatic int		ncr_intr(void *);
X
Xstatic int	si_generic(int adapter, int id, int lun,
X			 struct scsi_generic *cmd, int cmdlen,
X			 void *databuf, int datalen);
Xstatic int	si_group0(int adapter, int id, int lun,
X			    int opcode, int addr, int len,
X			    int flags, caddr_t databuf, int datalen);
X
Xstatic char scsi_name[] = "si";
X
Xstruct scsi_adapter	ncr5380_switch = {
X	ncr5380_scsi_cmd,		/* scsi_cmd()		*/
X	ncr5380_minphys,		/* scsi_minphys()	*/
X	NULL,				/* open_target_lu()	*/
X	NULL,				/* close_target_lu()	*/
X};
X
X/* This is copied from julian's bt driver */
X/* "so we have a default dev struct for our link struct." */
Xstruct scsi_device ncr_dev = {
X	NULL,		/* Use default error handler.	    */
X	NULL,		/* Use default start handler.		*/
X	NULL,		/* Use default async handler.	    */
X	NULL,		/* Use default "done" routine.	    */
X};
X
Xstatic int	si_match();
Xstatic void	si_attach();
X
Xstruct cfdriver sicd = {
X	NULL, "si", si_match, si_attach, DV_DULL,
X	sizeof(struct ncr5380_softc), NULL, 0,
X};
X
Xstatic int
Xsi_print(aux, name)
X	void *aux;
X	char *name;
X{
X}
X
Xstatic int
Xsi_match(parent, cf, aux)
X	struct device	*parent;
X	struct cfdata	*cf;
X	void		*aux;
X{
X	struct confargs *ca = aux;
X	struct romaux *ra = &ca->ca_ra;
X
X	/* Are we looking for the right thing? */
X	if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
X		return (0);
X
X	/* AFAIK, Sun 4s can only have an `si' on the VME16 (?) */
X	if (cputyp != CPU_SUN4 || ca->ca_bustype != BUS_VME16)
X		return (0);
X
X	/* Default interrupt priority always splbio==2 */
X	if (ra->ra_intr[0].int_pri == -1)
X		ra->ra_intr[0].int_pri == 2;
X
X	/* Make sure there is something there... */
X	if (probeget(ra->ra_vaddr + 1, 1) == -1)
X		return (0);
X
X	/*
X	 * We have to determine whether it is an `sc' (Sun2) or
X	 * `si' (Sun3) SCSI board.  This can be determined using
X	 * the fact that the `sc' board occupies 4K bytes in VME
X	 * space but the `si' board occupies 2K bytes.
X	 * Note that the `si' board should NOT respond to this.
X	 */
X	if (probeget(ra->ra_vaddr + 0x801, 1) != -1)
X		return(0);
X
X	return (1);
X}
X
Xstatic void
Xsi_attach(parent, self, aux)
X	struct device	*parent, *self;
X	void		*aux;
X{
X	struct ncr5380_softc *ncr5380 = (struct ncr5380_softc *) self;
X	volatile sci_regmap_t *regs;
X	struct confargs *ca = aux;
X	struct romaux *ra = &ca->ca_ra;
X
X	switch (ca->ca_bustype) {
X	case BUS_VME16:
X		regs = (sci_regmap_t *)
X		    mapiodev(ra->ra_paddr, sizeof(sci_regmap_t),
X		    ca->ca_bustype);
X		ncr5380->sc_ih.ih_fun = ncr_intr;
X		ncr5380->sc_ih.ih_arg = ncr5380;
X		vmeintr_establish(ra->ra_intr[0].int_vec,
X		    ra->ra_intr[0].int_pri, &ncr5380->sc_ih);
X		break;
X
X	default:
X		printf("unknown\n");
X		return;
X	}
X
X	ncr5380->sc_adapter_type = ca->ca_bustype;
X	ncr5380->sc_adapter_iv_am =
X		VME_SUPV_DATA_24 | (ra->ra_intr[0].int_vec & 0xFF);
X	ncr5380->sc_regs = regs;
X
X	/*
X	 * fill in the prototype scsi_link.
X	 */
X	ncr5380->sc_link.adapter_softc = ncr5380;
X	ncr5380->sc_link.adapter_target = 7;
X	ncr5380->sc_link.adapter = &ncr5380_switch;
X	ncr5380->sc_link.device = &ncr_dev;
X	ncr5380->sc_link.openings = 2;
X#ifdef	DEBUG
X	ncr5380->sc_link.flags |= si_flags;
X#endif
X
X	printf(" pri %d\n", ra->ra_intr[0].int_pri);
X	ncr5380_reset_adapter(ncr5380);
X	ncr5380_reset_scsibus(ncr5380);
X	config_found(self, &(ncr5380->sc_link), si_print);
X}
X
X#define MIN_PHYS	65536	/*BARF!!!!*/
Xstatic void
Xncr5380_minphys(struct buf *bp)
X{
X	if (bp->b_bcount > MIN_PHYS) {
X		printf("Uh-oh...  ncr5380_minphys setting bp->b_bcount = %x.\n", MIN_PHYS);
X		bp->b_bcount = MIN_PHYS;
X	}
X}
X#undef MIN_PHYS
X
Xstatic int
Xncr5380_scsi_cmd(struct scsi_xfer *xs)
X{
X	int flags, s, r;
X
X	flags = xs->flags;
X	if (xs->bp) flags |= (SCSI_NOSLEEP);
X	if ( flags & ITSDONE ) {
X		printf("Already done?");
X		xs->flags &= ~ITSDONE;
X	}
X	if ( ! ( flags & INUSE ) ) {
X		printf("Not in use?");
X		xs->flags |= INUSE;
X	}
X
X	s = splbio();
X
X	if ( flags & SCSI_RESET ) {
X		printf("flags & SCSIRESET.\n");
X		ncr5380_reset_scsibus(xs->sc_link->adapter_softc);
X		r = COMPLETE;
X	} else {
X		r = ncr5380_send_cmd(xs);
X		xs->flags |= ITSDONE;
X		scsi_done(xs);
X	}
X
X	splx(s);
X
X	switch(r) {
X	case COMPLETE:
X	case SUCCESSFULLY_QUEUED:
X		r = SUCCESSFULLY_QUEUED;
X		if (xs->flags & SCSI_POLL)
X			r = COMPLETE;
X		break;
X	default:
X		break;
X	}
X	return r;
X}
X
X#ifdef	DEBUG
Xstatic int
Xncr5380_show_scsi_cmd(struct scsi_xfer *xs)
X{
X	u_char	*b = (u_char *) xs->cmd;
X	int	i  = 0;
X
X	if ( ! ( xs->flags & SCSI_RESET ) ) {
X		printf("si(%d:%d:%d)-",
X			   xs->sc_link->scsibus,
X			   xs->sc_link->target,
X			   xs->sc_link->lun);
X		while (i < xs->cmdlen) {
X			if (i) printf(",");
X			printf("%x",b[i++]);
X		}
X		printf("-\n");
X	} else {
X		printf("si(%d:%d:%d)-RESET-\n",
X			   xs->sc_link->scsibus,
X			   xs->sc_link->target,
X			   xs->sc_link->lun);
X	}
X}
X#endif
X
X/*
X * Actual chip control.
X */
X
Xstatic void
Xncr_sbc_intr(struct ncr5380_softc *ncr5380)
X{
X	volatile sci_regmap_t *regs = ncr5380->sc_regs;
X
X	if ((regs->sci_csr & SCI_CSR_INT) == 0) {
X#ifdef	DEBUG
X		printf (" ncr_sbc_intr: spurrious\n");
X#endif
X		return;
X	}
X
X	SCI_CLR_INTR(regs);
X#ifdef	DEBUG
X	printf (" ncr_sbc_intr\n");
X#endif
X}
X
Xstatic void
Xncr_dma_intr(struct ncr5380_softc *ncr5380)
X{
X	volatile struct si_regs *regs = ncr5380->sc_regs;
X
X#ifdef	DEBUG
X	printf (" ncr_dma_intr\n");
X#endif
X}
X
Xstatic int
Xncr_intr(void *arg)
X{
X	struct ncr5380_softc *ncr5380 = arg;
X	volatile struct si_regs *si = ncr5380->sc_regs;
X	int rv = 0;
X
X	/* Interrupts not enabled?  Can not be for us. */
X	if ((si->si_csr & SI_CSR_INTR_EN) == 0)
X		return rv;
X
X	if (si->si_csr & SI_CSR_DMA_IP) {
X		ncr_dma_intr(ncr5380);
X		rv++;
X	}
X	if (si->si_csr & SI_CSR_SBC_IP) {
X		ncr_sbc_intr(ncr5380);
X		rv++;
X	}
X	return rv;
X}
X
Xstatic int
Xncr5380_reset_adapter(struct ncr5380_softc *sc)
X{
X	volatile struct si_regs *si = sc->sc_regs;
X
X#ifdef	DEBUG
X	if (si_debug) {
X		printf("si_reset_adapter\n");
X	}
X#endif
X
X	/* The reset bits in the CSR are active low. */
X	si->si_csr = 0;
X	delay(20);
X	si->si_csr = SI_CSR_FIFO_RES | SI_CSR_SCSI_RES;
X	si->fifo_count = 0;
X	if (sc->sc_adapter_type == BUS_VME16) {
X		si->dma_addrh = 0;
X		si->dma_addrl = 0;
X		si->dma_counth = 0;
X		si->dma_countl = 0;
X		si->iv_am = sc->sc_adapter_iv_am;
X	}
X}
X
Xstatic int
Xncr5380_reset_scsibus(struct ncr5380_softc *ncr5380)
X{
X	volatile sci_regmap_t *regs = ncr5380->sc_regs;
X
X#ifdef	DEBUG
X	if (si_debug) {
X		printf("si_reset_scsibus\n");
X	}
X#endif
X
X	regs->sci_icmd = SCI_ICMD_RST;
X	delay(100);
X	regs->sci_icmd = 0;
X
X	regs->sci_mode = 0;
X	regs->sci_tcmd = SCI_PHASE_DISC;
X	regs->sci_sel_enb = 0;
X
X	SCI_CLR_INTR(regs);
X	/* XXX - Need long delay here! */
X}
X
Xstatic int
Xncr5380_poll(int adapter, int timeout)
X{
X}
X
Xstatic int
Xncr5380_send_cmd(struct scsi_xfer *xs)
X{
X	int	sense;
X
X#ifdef	DIAGNOSTIC
X	if ((getsr() & PSL_IPL) < PSL_IPL2)
X		panic("ncr_send_cmd: bad spl");
X#endif
X
X#ifdef	DEBUG
X	if (si_debug & 2)
X		ncr5380_show_scsi_cmd(xs);
X#endif
X
X	sense = si_generic( xs->sc_link->scsibus, xs->sc_link->target,
X			  xs->sc_link->lun, xs->cmd, xs->cmdlen,
X			  xs->data, xs->datalen );
X
X	switch (sense) {
X	case 0:	/* success */
X		xs->resid = 0;
X		xs->error = XS_NOERROR;
X		break;
X
X	case 0x02:	/* Check condition */
X#ifdef	DEBUG
X		if (si_debug)
X			printf("check cond. target %d.\n",
X				   xs->sc_link->target);
X#endif
X		delay(10);	/* Phil's fix for slow devices. */
X		si_group0(xs->sc_link->scsibus,
X				  xs->sc_link->target,
X				  xs->sc_link->lun,
X				  0x3, 0x0,
X				  sizeof(struct scsi_sense_data),
X				  0, (caddr_t) &(xs->sense),
X				  sizeof(struct scsi_sense_data));
X		xs->error = XS_SENSE;
X		break;
X	case 0x08:	/* Busy - common code will delay, retry. */
X		xs->error = XS_BUSY;
X		break;
X	default:	/* Dead - tell common code to give up. */
X		xs->error = XS_DRIVER_STUFFUP;
X		break;
X
X	}
X	return (COMPLETE);
X}
X
Xstatic int
Xsi_select_target(register volatile sci_regmap_t *regs,
X	      u_char myid, u_char tid, int with_atn)
X{
X	register u_char	bid, icmd;
X	int		ret = SCSI_RET_RETRY;
X	int 	arb_retries, arb_wait;
X	int i;
X	volatile u_char vuc;
X
X	/* for our purposes.. */
X	myid = 1 << myid;
X	tid = 1 << tid;
X
X	regs->sci_sel_enb = 0; /* we don't want any interrupts. */
X	regs->sci_tcmd = 0;	/* get into a harmless state */
X
X	arb_retries = ARBITRATION_RETRIES;
X
Xretry_arbitration:
X	regs->sci_mode = 0;	/* get into a harmless state */
X	if (--arb_retries <= 0) {
X#ifdef	DEBUG
X		if (si_debug) {
X			printf("si_select: arb_retries expended; resetting...\n");
X		}
X#endif
X		ret = SCSI_RET_NEED_RESET;
X		goto nosel;
X	}
X
X	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
X
X	/* Picked this constant for convenience. --thorpej */
X	for (i = 0; i < ARBITRATION_RETRIES; ++i) {
X		vuc = (regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL));
X		if (vuc == 0)
X			break;
X		delay(10);
X	}
X	if (vuc != 0) {
X		/* No sir, I don't like it.  Call for a reset. */
X#ifdef DEBUG
X		if (si_debug)
X			printf("si_select_target: still BSY+SEL; resetting\n");
X#endif
X		ret = SCSI_RET_NEED_RESET;
X		goto nosel;
X	}
X
X	regs->sci_odata = myid;
X	regs->sci_mode = SCI_MODE_ARB;
X/*	regs->sci_mode |= SCI_MODE_ARB;	XXX? */
X
X	/* AIP might not set if BSY went true after we checked */
X	/* Wait up to about 100 usec. for it to appear. */
X	arb_wait = 50;	/* X2 */
X	do {
X		if (regs->sci_icmd & SCI_ICMD_AIP)
X			goto got_aip;
X		delay(2);
X	} while (--arb_wait > 0);
X	/* XXX - Could have missed it? */
X#ifdef	DEBUG
X	if (si_debug)
X		printf("si_select_target: API did not appear\n");
X#endif
X	goto retry_arbitration;
X
X	got_aip:
X#ifdef	DEBUG
X	if (si_debug & 4) {
X		printf("si_select_target: API after %d tries (last wait %d)\n",
X			   ARBITRATION_RETRIES - arb_retries,
X			   (50 - arb_wait));
X	}
X#endif
X
X	delay(3);	/* 2.2 uSec. arbitration delay */
X
X	if (regs->sci_icmd & SCI_ICMD_LST) {
X#ifdef	DEBUG
X		if (si_debug)
X			printf ("lost 1\n");
X#endif
X		goto retry_arbitration;	/* XXX */
X	}
X
X	regs->sci_mode &= ~SCI_MODE_PAR_CHK;
X	bid = regs->sci_data;
X
X	if ((bid & ~myid) > myid) {
X#ifdef	DEBUG
X		if (si_debug)
X			printf ("lost 2\n");
X#endif
X		/* Trying again will not help. */
X		goto lost;
X	}
X	if (regs->sci_icmd & SCI_ICMD_LST) {
X#ifdef	DEBUG
X		if (si_debug)
X			printf ("lost 3\n");
X#endif
X		goto lost;
X	}
X
X	/* Won arbitration, enter selection phase now */	
X	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
X	icmd |= (with_atn ? (SCI_ICMD_SEL|SCI_ICMD_ATN) : SCI_ICMD_SEL);
X	regs->sci_icmd = icmd;
X
X	if (regs->sci_icmd & SCI_ICMD_LST) {
X#ifdef	DEBUG
X		if (si_debug)
X			printf ("nosel\n");
X#endif
X		goto nosel;
X	}
X
X	/* XXX a target that violates specs might still drive the bus XXX */
X	/* XXX should put our id out, and after the delay check nothi XXX */
X	/* XXX ng else is out there.				      XXX */
X
X	delay(3);
X
X	regs->sci_sel_enb = 0;
X
X	regs->sci_odata = myid | tid;
X
X	icmd |= SCI_ICMD_BSY|SCI_ICMD_DATA;
X	regs->sci_icmd = icmd;
X
X/*	regs->sci_mode &= ~SCI_MODE_ARB;	 2 deskew delays, too */
X	regs->sci_mode = 0;			/* 2 deskew delays, too */
X	
X	icmd &= ~SCI_ICMD_BSY;
X	regs->sci_icmd = icmd;
X
X	/* bus settle delay, 400ns */
X	delay(3);
X
X	regs->sci_mode |= SCI_MODE_PAR_CHK;
X
X	{
X		register int timeo  = 2500;/* 250 msecs in 100 usecs chunks */
X		while ((regs->sci_bus_csr & SCI_BUS_BSY) == 0) {
X			if (--timeo > 0) {
X				delay(100);
X			} else {
X				/* This is the "normal" no-such-device select error. */
X#ifdef	DEBUG
X				if (si_debug)
X					printf("si_select: not BSY (nothing there)\n");
X#endif
X				goto nodev;
X			}
X		}
X	}
X
X	icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_SEL);
X	regs->sci_icmd = icmd;
X/*	regs->sci_sel_enb = myid;*/	/* looks like we should NOT have it */
X	/* XXX - SCI_MODE_PAR_CHK ? */
X	return SCSI_RET_SUCCESS;
X
Xnodev:
X	ret = SCSI_RET_DEVICE_DOWN;
X	regs->sci_sel_enb = myid;
Xnosel:
X	regs->sci_icmd = 0;
X	regs->sci_mode = 0;
X	return ret;
X
Xlost:
X	regs->sci_icmd = 0;
X	regs->sci_mode = 0;
X#ifdef	DEBUG
X	if (si_debug) {
X		printf("si_select: lost arbitration\n");
X	}
X#endif
X	return ret;
X}
X
Xsci_data_out(regs, phase, count, data)
X	register volatile sci_regmap_t	*regs;
X	unsigned char		*data;
X{
X	register unsigned char	icmd;
X	register int		cnt=0;
X
X	/* ..checks.. */
X
X	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
Xloop:
X	if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
X		return cnt;
X
X	WAIT_FOR_REQ(regs);
X	icmd |= SCI_ICMD_DATA;
X	regs->sci_icmd = icmd;
X	regs->sci_odata = *data++;
X	icmd |= SCI_ICMD_ACK;
X	regs->sci_icmd = icmd;
X
X	icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_ACK);
X	WAIT_FOR_NOT_REQ(regs);
X	regs->sci_icmd = icmd;
X	++cnt;
X	if (--count > 0)
X		goto loop;
Xscsi_timeout_error:
X	return cnt;
X}
X
Xsci_data_in(regs, phase, count, data)
X	register volatile sci_regmap_t	*regs;
X	unsigned char		*data;
X{
X	register unsigned char	icmd;
X	register int		cnt=0;
X
X	/* ..checks.. */
X
X	icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
X
Xloop:
X	if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
X		return cnt;
X
X	WAIT_FOR_REQ(regs);
X	*data++ = regs->sci_data;
X	icmd |= SCI_ICMD_ACK;
X	regs->sci_icmd = icmd;
X
X	icmd &= ~SCI_ICMD_ACK;
X	WAIT_FOR_NOT_REQ(regs);
X	regs->sci_icmd = icmd;
X	++cnt;
X	if (--count > 0)
X		goto loop;
X
Xscsi_timeout_error:
X	return cnt;
X}
X
X/* Return -1 (error) or number of bytes sent (>=0). */
Xstatic int
Xsi_command_transfer(register volatile sci_regmap_t *regs,
X		 int maxlen, u_char *data, u_char *status, u_char *msg)
X{
X	int	xfer, phase;
X
X	xfer = 0;
X	regs->sci_icmd = 0;
X
X	while (1) {
X
X		WAIT_FOR_REQ(regs);
X
X		phase = SCI_CUR_PHASE(regs->sci_bus_csr);
X
X		switch (phase) {
X			case SCSI_PHASE_CMD:
X				SCI_ACK(regs,SCSI_PHASE_CMD);
X				xfer += sci_data_out(regs, SCSI_PHASE_CMD,
X						   	maxlen, data);
X				goto out;
X
X			case SCSI_PHASE_DATA_IN:
X				printf("command_transfer: Data in phase?\n");
X				goto err;
X
X			case SCSI_PHASE_DATA_OUT:
X				printf("command_transfer: Data out phase?\n");
X				goto err;
X
X			case SCSI_PHASE_STATUS:
X				SCI_ACK(regs,SCSI_PHASE_STATUS);
X				printf("command_transfer: status in...\n");
X				sci_data_in(regs, SCSI_PHASE_STATUS,
X					  	1, status);
X				printf("command_transfer: status=0x%x\n", *status);
X				goto err;
X
X			case SCSI_PHASE_MESSAGE_IN:
X				SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
X				printf("command_transfer: msg in?\n");
X				sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
X					  	1, msg);
X				break;
X
X			case SCSI_PHASE_MESSAGE_OUT:
X				SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
X				sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
X					  	1, msg);
X				break;
X
X			default:
X				printf("command_transfer: Unexpected phase 0x%x\n", phase);
X				goto err;
X		}
X	}
Xscsi_timeout_error:
X err:
X	xfer = -1;
X out:
X	return xfer;
X}
X
Xstatic int
Xsi_data_transfer(register volatile sci_regmap_t *regs,
X	      int maxlen, u_char *data, u_char *status, u_char *msg)
X{
X	int	retlen = 0, xfer, phase;
X
X	regs->sci_icmd = 0;
X
X	*status = 0;
X
X	while (1) {
X
X		WAIT_FOR_REQ(regs);
X
X		phase = SCI_CUR_PHASE(regs->sci_bus_csr);
X
X		switch (phase) {
X			case SCSI_PHASE_CMD:
X				printf("Command phase in data_transfer().\n");
X				return retlen;
X			case SCSI_PHASE_DATA_IN:
X				SCI_ACK(regs,SCSI_PHASE_DATA_IN);
X#if PSEUDO_DMA
X				xfer = sci_pdma_in(regs, SCSI_PHASE_DATA_IN,
X						  	maxlen, data);
X#else
X				xfer = sci_data_in(regs, SCSI_PHASE_DATA_IN,
X						  	maxlen, data);
X#endif
X				retlen += xfer;
X				maxlen -= xfer;
X				break;
X			case SCSI_PHASE_DATA_OUT:
X				SCI_ACK(regs,SCSI_PHASE_DATA_OUT);
X#if PSEUDO_DMA
X				xfer = sci_pdma_out(regs, SCSI_PHASE_DATA_OUT,
X						   	maxlen, data);
X#else
X				xfer = sci_data_out(regs, SCSI_PHASE_DATA_OUT,
X						   	maxlen, data);
X#endif
X				retlen += xfer;
X				maxlen -= xfer;
X				break;
X			case SCSI_PHASE_STATUS:
X				SCI_ACK(regs,SCSI_PHASE_STATUS);
X				sci_data_in(regs, SCSI_PHASE_STATUS,
X					  	1, status);
X				break;
X			case SCSI_PHASE_MESSAGE_IN:
X				SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
X				sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
X					  	1, msg);
X				if (*msg == 0) {
X					return retlen;
X				} else {
X					printf( "message 0x%x in "
X						"data_transfer.\n", *msg);
X				}
X				break;
X			case SCSI_PHASE_MESSAGE_OUT:
X				SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
X				sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
X					  	1, msg);
X				break;
X			default:
X				printf( "Unexpected phase 0x%x in "
X					"data_transfer().\n", phase);
Xscsi_timeout_error:
X				return retlen;
X				break;
X		}
X	}
X}
X
Xstatic int
Xsi_dorequest(struct ncr5380_softc *sc,
X	int target, int lun, u_char *cmd, int cmdlen,
X	char *databuf, int datalen, int *sent)
X	/* Returns 0 on success, -1 on internal error, or the status byte */
X{
X	register volatile sci_regmap_t *regs = sc->sc_regs;
X	int	cmd_bytes_sent, r;
X	u_char	stat, msg, c;
X
X#ifdef	DEBUG
X	if (si_debug) {
X		printf("si_dorequest: target=%d, lun=%d\n", target, lun);
X	}
X#endif
X
X	*sent = 0;
X
X	if ( ( r = si_select_target(regs, 7, target, 1) ) != SCSI_RET_SUCCESS) {
X#ifdef	DEBUG
X		if (si_debug) {
X			printf("si_dorequest: select returned %d\n", r);
X		}
X#endif
X
X		SCI_CLR_INTR(regs);
X		switch (r) {
X
X		case SCSI_RET_NEED_RESET:
X			printf("si_dorequest: target=%d, lun=%d, r=%d resetting...\n",
X				   target, lun, r);
X			ncr5380_reset_adapter(sc);
X			ncr5380_reset_scsibus(sc);
X			/* fall through */
X		case SCSI_RET_RETRY:
X			return 0x08;	/* Busy - tell common code to retry. */
X
X		default:
X			printf("si_dorequest: target=%d, lun=%d, error=%d.\n",
X				target, lun, r);
X			/* fall through */
X		case SCSI_RET_DEVICE_DOWN:
X			return -1;	/* Dead - tell common code to give up. */
X		}
X	}
X
X	c = 0x80 | lun;
X
X	if ((cmd_bytes_sent = si_command_transfer(regs, cmdlen,
X				(u_char *) cmd, &stat, &c)) != cmdlen)
X	{
X		SCI_CLR_INTR(regs);
X		if (cmd_bytes_sent >= 0) {
X			printf("Data underrun sending CCB (%d bytes of %d, sent).\n",
X				   cmd_bytes_sent, cmdlen);
X		}
X		return -1;
X	}
X
X	*sent = si_data_transfer(regs, datalen, (u_char *)databuf,
X				  &stat, &msg);
X#ifdef	DEBUG
X	if (si_debug) {
X		printf("si_dorequest: data transfered = %d\n", *sent);
X	}
X#endif
X
X	return stat;
X}
X
Xstatic int
Xsi_generic(int adapter, int id, int lun, struct scsi_generic *cmd,
X  	 int cmdlen, void *databuf, int datalen)
X{
X	register struct ncr5380_softc *sc = sicd.cd_devs[adapter];
X	int i, j, sent;
X
X	if (cmd->opcode == TEST_UNIT_READY)	/* XXX */
X		cmd->bytes[0] = ((u_char) lun << 5);
X
X	i = si_dorequest(sc, id, lun, (u_char *) cmd, cmdlen,
X					 databuf, datalen, &sent);
X
X	return i;
X}
X
Xstatic int
Xsi_group0(int adapter, int id, int lun, int opcode, int addr, int len,
X		int flags, caddr_t databuf, int datalen)
X{
X	register struct ncr5380_softc *sc = sicd.cd_devs[adapter];
X	unsigned char cmd[6];
X	int i, j, sent;
X
X	cmd[0] = opcode;		/* Operation code           		*/
X	cmd[1] = (lun << 5) | ((addr >> 16) & 0x1F);	/* Lun & MSB of addr	*/
X	cmd[2] = (addr >> 8) & 0xFF;	/* addr					*/
X	cmd[3] = addr & 0xFF;		/* LSB of addr				*/
X	cmd[4] = len;			/* Allocation length			*/
X	cmd[5] = flags;		/* Link/Flag				*/
X
X	i = si_dorequest(sc, id, lun, cmd, 6, databuf, datalen, &sent);
X
X	return i;
X}
END-of-si.c
echo x - sidefs.h
sed 's/^X//' >sidefs.h << 'END-of-sidefs.h'
X/*	$NetBSD: scsi_defs.h,v 1.4 1995/06/01 20:22:17 gwr Exp $	*/
X
X/*-
X * Copyright (C) 1993	Allen K. Briggs, Chris P. Caputo,
X *			Michael L. Finch, Bradley A. Grantham, and
X *			Lawrence A. Kesteloot
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X *    must display the following acknowledgement:
X *	This product includes software developed by the Alice Group.
X * 4. The names of the Alice Group or any of its members may not be used
X *    to endorse or promote products derived from this software without
X *    specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
X * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
X * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
X#ifndef _SCSI_DEFS_H
X#define _SCSI_DEFS_H
X
X#define SCSI_PHASE_DATA_OUT	0x0
X#define SCSI_PHASE_DATA_IN	0x1
X#define SCSI_PHASE_CMD		0x2
X#define SCSI_PHASE_STATUS	0x3
X#define SCSI_PHASE_UNSPEC1	0x4
X#define SCSI_PHASE_UNSPEC2	0x5
X#define SCSI_PHASE_MESSAGE_OUT	0x6
X#define SCSI_PHASE_MESSAGE_IN	0x7
X
X#define SCSI_PHASE(x)	((x)&0x7)
X
X/* These should be fixed up. */
X
X#define SCSI_RET_SUCCESS	0
X#define SCSI_RET_RETRY		1
X#define SCSI_RET_DEVICE_DOWN	2
X#define SCSI_RET_COMMAND_FAIL	3
X#define SCSI_RET_NEED_RESET 	4
X
X#endif
END-of-sidefs.h
echo x - sireg.h
sed 's/^X//' >sireg.h << 'END-of-sireg.h'
X/*	$NetBSD: scsi_sunsi.h,v 1.2 1995/06/01 20:22:27 gwr Exp $	*/
X
X/*
X * Register map for the Sun3 SCSI Interface (si)
X * The first part of this register map is an NCR5380
X * SCSI Bus Interface Controller (SBIC).  The rest is a
X * DMA controller and custom logic in one of two flavors,
X * one for the OBIO interface (3/50,3/60) and one for the
X * VME interface (3/160,3/260,etc.), where some registers
X * are implemented only on one or the other, some on both.
X */
X
X/*
X * Some of these registers apply to only one interface and some
X * apply to both. The registers which apply to the Sun3/50 onboard 
X * version only are udc_rdata and udc_raddr. The registers which
X * apply to the Sun3 vme version only are dma_addr, dma_count, bpr,
X * iv_am, and bcrh. Thus, the sbc registers, fifo_data, bcr, and csr 
X * apply to both interfaces.
X * One other feature of the vme interface: a write to the dma count 
X * register also causes a write to the fifo byte count register and
X * vis versa.
X */
X
Xstruct si_regs {
X	sci_regmap_t sci;	/* See ncr5380.h */
X	/* DMA controller registers */
X	u_short			dma_addrh;	/* dma address (VME only) */
X	u_short			dma_addrl;	/* (high word, low word)  */
X	u_short			dma_counth;	/* dma count   (VME only) */
X	u_short			dma_countl;	/* (high word, low word)  */
X
X	/* AMD 9516 regs (OBIO only) see am9516.h */
X	u_short			udc_data;	/* Am9516, reg data (OBIO only) */
X	u_short			udc_addr;	/* Am9516, reg addr (OBIO only) */
X
X	/* These three registers are on both OBIO and VME versions. */
X	u_short			fifo_data;	/* fifo data register */
X						/* holds extra byte on odd */
X						/* byte dma read */
X	u_short			fifo_count;		/* fifo byte count */
X	u_short			si_csr;		/* control/status register */
X
X	/* The rest of these are on the VME interface only: */
X	u_short			bprh;		/* byte pack, high (VME only) */
X	u_short			bprl;		/* byte pack, low  (VME only) */
X	u_short			iv_am;		/* bits 0-7: intr vector */
X						/* bits 8-13: addr modifier (VME only) */
X						/* bits 14-15: unused */
X	u_short			bcrh;		/* high portion of bcr (VME only) */
X};
X
X/* possible values for the address modifier, sun3 vme version only */
X#define VME_SUPV_DATA_24	0x3d00
X
X/* XXX - must massage dvma addresses for Sun3/50 hardware (?) */
X#define DVMA_OFFSET		(int)(DVMA - (char *)KERNELBASE)
X
X/*
X * Status Register.
X * Note:
X *	(r)	indicates bit is read only.
X *	(rw)	indicates bit is read or write.
X *	(v)	vme host adaptor interface only.
X *	(o)	sun3/50 onboard host adaptor interface only.
X *	(b)	both vme and sun3/50 host adaptor interfaces.
X */
X#define SI_CSR_DMA_ACTIVE	0x8000	/* (r,o) dma transfer active */
X#define SI_CSR_DMA_CONFLICT	0x4000	/* (r,b) reg accessed while dmaing */
X#define SI_CSR_DMA_BUS_ERR	0x2000	/* (r,b) bus error during dma */
X#define SI_CSR_ID		0x1000	/* (r,b) 0 for 3/50, 1 for SCSI-3, */
X					/* 0 if SCSI-3 unmodified */
X#define SI_CSR_FIFO_FULL	0x0800	/* (r,b) fifo full */
X#define SI_CSR_FIFO_EMPTY	0x0400	/* (r,b) fifo empty */
X#define SI_CSR_SBC_IP		0x0200	/* (r,b) sbc interrupt pending */
X#define SI_CSR_DMA_IP		0x0100	/* (r,b) dma interrupt pending */
X#define SI_CSR_LOB		0x00c0	/* (r,v) number of leftover bytes */
X#define SI_CSR_LOB_THREE	0x00c0	/* (r,v) three leftover bytes */
X#define SI_CSR_LOB_TWO		0x0080	/* (r,v) two leftover bytes */
X#define SI_CSR_LOB_ONE		0x0040	/* (r,v) one leftover byte */
X#define SI_CSR_BPCON		0x0020	/* (rw,v) byte packing control */
X					/* dma is in 0=longwords, 1=words */
X#define SI_CSR_DMA_EN		0x0010	/* (rw,v) dma enable */
X#define SI_CSR_SEND		0x0008	/* (rw,b) dma dir, 1=to device */
X#define SI_CSR_INTR_EN		0x0004	/* (rw,b) interrupts enable */
X#define SI_CSR_FIFO_RES		0x0002	/* (rw,b) inits fifo, 0=reset */
X#define SI_CSR_SCSI_RES		0x0001	/* (rw,b) reset sbc and udc, 0=reset */
X
END-of-sireg.h
exit