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