summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1997-12-01 18:58:50 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1997-12-01 18:58:50 +0000
commit19999945980d3554ff5326874707c88a83b15413 (patch)
treeb0bd6c0f065281e97d126d885ae8f5992a06cd67 /sys/dev/pci
parent99805af754b0857a8696bb45a767d00e28718eed (diff)
Newer ncr driver from NetBSD minus the scsipi stuff and with
changes to make it diff usefully against the FreeBSD driver. Tested on alpha and i386, not tested on powerpc.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/ncr.c2877
-rw-r--r--sys/dev/pci/ncrreg.h665
2 files changed, 2448 insertions, 1094 deletions
diff --git a/sys/dev/pci/ncr.c b/sys/dev/pci/ncr.c
index fb74a3bb21e..b2458859639 100644
--- a/sys/dev/pci/ncr.c
+++ b/sys/dev/pci/ncr.c
@@ -1,9 +1,11 @@
-/* $OpenBSD: ncr.c,v 1.31 1997/10/11 11:05:27 pefo Exp $ */
-/* $NetBSD: ncr.c,v 1.56 1997/03/04 21:42:34 mycroft Exp $ */
+/* $OpenBSD: ncr.c,v 1.32 1997/12/01 18:58:48 millert Exp $ */
+/* $NetBSD: ncr.c,v 1.63 1997/09/23 02:39:15 perry Exp $ */
/**************************************************************************
**
-** Device driver for the NCR 53C810 PCI-SCSI-Controller.
+** Id: ncr.c,v 1.112 1997/11/07 09:20:56 phk Exp
+**
+** Device driver for the NCR 53C8xx PCI-SCSI-Controller.
**
** FreeBSD / NetBSD / OpenBSD
**
@@ -55,10 +57,6 @@
#define NCR_GETCC_WITHMSG
-#ifdef __OpenBSD__
-#define __BROKEN_INDIRECT_CONFIG
-#endif
-
#if defined (__FreeBSD__) && defined(KERNEL)
#include "opt_ncr.h"
#endif /* defined (__FreeBSD__) && defined(KERNEL) */
@@ -90,13 +88,35 @@
#endif /* SCSI_NCR_MYADDR */
/*
-** The maximal synchronous frequency in kHz.
+** The default synchronous period factor
** (0=asynchronous)
+** If maximum synchronous frequency is defined, use it instead.
*/
-#ifndef SCSI_NCR_MAX_SYNC
-#define SCSI_NCR_MAX_SYNC (10000)
-#endif /* SCSI_NCR_MAX_SYNC */
+#ifndef SCSI_NCR_MAX_SYNC
+
+#ifndef SCSI_NCR_DFLT_SYNC
+#define SCSI_NCR_DFLT_SYNC (12)
+#endif /* SCSI_NCR_DFLT_SYNC */
+
+#else
+
+#if SCSI_NCR_MAX_SYNC == 0
+#define SCSI_NCR_DFLT_SYNC 0
+#else
+#define SCSI_NCR_DFLT_SYNC (250000 / SCSI_NCR_MAX_SYNC)
+#endif
+
+#endif
+
+/*
+** The minimal asynchronous pre-scaler period (ns)
+** Shall be 40.
+*/
+
+#ifndef SCSI_NCR_MIN_ASYNC
+#define SCSI_NCR_MIN_ASYNC (40)
+#endif /* SCSI_NCR_MIN_ASYNC */
/*
** The maximal bus with (in log2 byte)
@@ -160,10 +180,10 @@
/*
** The maximum transfer length (should be >= 64k).
-** MUST NOT be greater than (MAX_SCATTER-1) * NBPG.
+** MUST NOT be greater than (MAX_SCATTER-1) * PAGE_SIZE.
*/
-#define MAX_SIZE ((MAX_SCATTER-1) * (long) NBPG)
+#define MAX_SIZE ((MAX_SCATTER-1) * (long) PAGE_SIZE)
/*
** other
@@ -178,39 +198,35 @@
**==========================================================
*/
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
#ifdef _KERNEL
#define KERNEL
#endif
+#else
+#include <stddef.h>
#endif
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
-#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
-#include <sys/proc.h>
#ifdef KERNEL
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/buf.h>
#include <sys/kernel.h>
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-#define bootverbose 1
-#endif
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+#ifndef __OpenBSD__
#include <sys/sysctl.h>
#include <machine/clock.h>
#endif
#include <vm/vm.h>
-#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>
#endif /* KERNEL */
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+#ifndef __OpenBSD__
#include <pci/pcivar.h>
#include <pci/pcireg.h>
#include <pci/ncrreg.h>
@@ -218,18 +234,34 @@
#include <sys/device.h>
#include <machine/bus.h>
#include <machine/intr.h>
-#include <dev/pci/ncr_reg.h>
+#include <dev/pci/ncrreg.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#if !defined(__alpha__) && !defined(__powerpc__)
+#ifndef __alpha__
#define DELAY(x) delay(x)
#endif
-#endif /* __NetBSD__ || __OpenBSD__ */
-
#include <scsi/scsi_all.h>
+#endif /* __OpenBSD__ */
+
#include <scsi/scsiconf.h>
-#if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(__alpha__)
+#ifdef __OpenBSD__ /* XXX */
+#define __BROKEN_INDIRECT_CONFIG
+#undef PAGE_SIZE
+#undef PAGE_MASK
+#define PAGE_SIZE NBPG
+#define PAGE_MASK (NBPG-1)
+#endif
+
+#ifdef __OpenBSD__
+#ifdef NCR_VERBOSE
+#define bootverbose NCR_VERBOSE
+#else
+#define bootverbose 0
+#endif
+#endif
+
+#if defined(__OpenBSD__) && defined(__alpha__)
/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
#undef vtophys
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
@@ -298,58 +330,50 @@
**==========================================================
*/
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-
-#ifdef NCR_IOMAPPED
+#ifdef __OpenBSD__
#define INB(r) \
INB_OFF(offsetof(struct ncr_reg, r))
#define INB_OFF(o) \
- bus_space_read_1 (np->sc_memt, np->sc_bah, (o))
+ bus_space_read_1 (np->sc_st, np->sc_sh, (o))
#define INW(r) \
- bus_space_read_2 (np->sc_memt, np->sc_bah, offsetof(struct ncr_reg, r))
+ bus_space_read_2 (np->sc_st, np->sc_sh, offsetof(struct ncr_reg, r))
#define INL(r) \
INL_OFF(offsetof(struct ncr_reg, r))
#define INL_OFF(o) \
- bus_space_read_4 (np->sc_memt, np->sc_bah, (o))
+ bus_space_read_4 (np->sc_st, np->sc_sh, (o))
#define OUTB(r, val) \
- bus_space_write_1 (np->sc_memt, np->sc_bah, offsetof(struct ncr_reg, r), (val))
+ bus_space_write_1 (np->sc_st, np->sc_sh, offsetof(struct ncr_reg, r), (val))
#define OUTW(r, val) \
- bus_space_write_2 (np->sc_memt, np->sc_bah, offsetof(struct ncr_reg, r), (val))
+ bus_space_write_2 (np->sc_st, np->sc_sh, offsetof(struct ncr_reg, r), (val))
#define OUTL(r, val) \
OUTL_OFF(offsetof(struct ncr_reg, r), (val))
#define OUTL_OFF(o, val) \
- bus_space_write_4 (np->sc_memt, np->sc_bah, (o), (val))
+ bus_space_write_4 (np->sc_st, np->sc_sh, (o), (val))
-#else
+#define READSCRIPT_OFF(base, off) \
+ SCR_BO(base ? *((int32_t *)((char *)base + (off))) : \
+ bus_space_read_4 (np->ram_tag, np->ram_handle, off))
-#define INB(r) \
- INB_OFF(offsetof(struct ncr_reg, r))
-#define INB_OFF(o) \
- bus_space_read_1 (np->sc_memt, np->sc_bah, (o))
-#define INW(r) \
- bus_space_read_2 (np->sc_memt, np->sc_bah, offsetof(struct ncr_reg, r))
-#define INL(r) \
- INL_OFF(offsetof(struct ncr_reg, r))
-#define INL_OFF(o) \
- bus_space_read_4 (np->sc_memt, np->sc_bah, (o))
+#define WRITESCRIPT_OFF(base, off, val) \
+ do { \
+ if (base) \
+ *((int32_t *)((char *)base + (off))) = (SCR_BO(val)); \
+ else \
+ bus_space_write_4 (np->ram_tag, np->ram_handle, off, SCR_BO(val)); \
+ } while (0)
-#define OUTB(r, val) \
- bus_space_write_1 (np->sc_memt, np->sc_bah, offsetof(struct ncr_reg, r), (val))
-#define OUTW(r, val) \
- bus_space_write_2 (np->sc_memt, np->sc_bah, offsetof(struct ncr_reg, r), (val))
-#define OUTL(r, val) \
- OUTL_OFF(offsetof(struct ncr_reg, r), (val))
-#define OUTL_OFF(o, val) \
- bus_space_write_4 (np->sc_memt, np->sc_bah, (o), (val))
+#define READSCRIPT(r) \
+ READSCRIPT_OFF(np->script, offsetof(struct script, r))
-#endif
+#define WRITESCRIPT(r, val) \
+ WRITESCRIPT_OFF(np->script, offsetof(struct script, r), val)
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#else /* !__OpenBSD__ */
#ifdef NCR_IOMAPPED
-
+
#define INB(r) inb (np->port + offsetof(struct ncr_reg, r))
#define INB_OFF(o) inb (np->port + (o))
#define INW(r) inw (np->port + offsetof(struct ncr_reg, r))
@@ -364,19 +388,34 @@
#else
#define INB(r) (np->reg->r)
-#define INB_OFF(o) (*((volatile INT8 *)((char *)np->reg + (o))))
+#define INB_OFF(o) (*((volatile int8_t *)((char *)np->reg + (o))))
#define INW(r) (np->reg->r)
#define INL(r) (np->reg->r)
-#define INL_OFF(o) (*((volatile INT32 *)((char *)np->reg + (o))))
+#define INL_OFF(o) (*((volatile int32_t *)((char *)np->reg + (o))))
#define OUTB(r, val) np->reg->r = (val)
#define OUTW(r, val) np->reg->r = (val)
#define OUTL(r, val) np->reg->r = (val)
-#define OUTL_OFF(o, val) *((volatile INT32 *)((char *)np->reg + (o))) = val
+#define OUTL_OFF(o, val) *((volatile int32_t *)((char *)np->reg + (o))) = val
#endif
-#endif /* __NetBSD__ || __OpenBSD__ */
+#define READSCRIPT_OFF(base, off) (*((int32_t *)((char *)base + (off))))
+#define READSCRIPT(r) (np->script->r)
+#define WRITESCRIPT(r, val) np->script->r = (val)
+
+#endif /* __OpenBSD__ */
+
+/*
+** Set bit field ON, OFF
+*/
+
+#define OUTONB(r, m) OUTB(r, INB(r) | (m))
+#define OUTOFFB(r, m) OUTB(r, INB(r) & ~(m))
+#define OUTONW(r, m) OUTW(r, INW(r) | (m))
+#define OUTOFFW(r, m) OUTW(r, INW(r) & ~(m))
+#define OUTONL(r, m) OUTL(r, INL(r) | (m))
+#define OUTOFFL(r, m) OUTL(r, INL(r) & ~(m))
/*==========================================================
**
@@ -485,7 +524,7 @@
**
** OS dependencies.
**
-** Note that various types are defined in ncr_reg.h.
+** Note that various types are defined in ncrreg.h.
**
**==========================================================
*/
@@ -627,6 +666,14 @@ struct tcb {
ccb_p hold_cp;
/*
+ ** pointer to ccb used for negotiating.
+ ** Avoid to start a nego for all queued commands
+ ** when tagged command queuing is enabled.
+ */
+
+ ccb_p nego_cp;
+
+ /*
** statistical data
*/
@@ -766,9 +813,9 @@ struct head {
** the last transfer command.
*/
- u_long savep;
- u_long lastp;
- u_long goalp;
+ u_int32_t savep;
+ u_int32_t lastp;
+ u_int32_t goalp;
/*
** The virtual address of the ccb
@@ -795,7 +842,7 @@ struct head {
** The status bytes are used by the host and the script processor.
**
** The first four byte are copied to the scratchb register
-** (declared as scr0..scr3 in ncr_reg.h) just after the select/reselect,
+** (declared as scr0..scr3 in ncrreg.h) just after the select/reselect,
** and copied back just after disconnecting.
** Inside the script the XX_REG are used.
**
@@ -899,6 +946,12 @@ struct dsb {
struct ccb {
/*
+ ** This filler ensures that the global header is
+ ** cache line size aligned.
+ */
+ ncrcmd filler[4];
+
+ /*
** during reselection the ncr jumps to this point.
** If a "SIMPLE_TAG" message was received,
** then SFBR is set to the tag.
@@ -1016,15 +1069,24 @@ struct ccb {
*/
struct ncb {
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+ /*
+ ** The global header.
+ ** Accessible to both the host and the
+ ** script-processor.
+ ** We assume it is cache line size aligned.
+ */
+ struct head header;
+
+#ifdef __OpenBSD__
struct device sc_dev;
- void *sc_ih;
- bus_space_tag_t sc_memt;
pci_chipset_tag_t sc_pc;
- bus_space_handle_t sc_bah;
-#else /* !(__NetBSD__ || __OpenBSD__) */
+ void *sc_ih;
+ bus_space_tag_t sc_st;
+ bus_space_handle_t sc_sh;
+ int sc_iomapped;
+#else /* !__OpenBSD__ */
int unit;
-#endif /* __NetBSD__ || __OpenBSD__ */
+#endif /* __OpenBSD__ */
/*-----------------------------------------------
** Scripts ..
@@ -1047,14 +1109,20 @@ struct ncb {
** virtual and physical addresses
** of the 53c810 chip.
*/
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+#ifdef __OpenBSD__
+ bus_addr_t paddr;
+
+ bus_space_tag_t ram_tag;
+ bus_space_handle_t ram_handle;
+ bus_addr_t paddr2;
+ int scriptmapped;
+#else
vm_offset_t vaddr;
vm_offset_t paddr;
-#else
- bus_addr_t paddr;
-#endif
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+ vm_offset_t vaddr2;
+ vm_offset_t paddr2;
+
/*
** pointer to the chip's registers.
*/
@@ -1063,25 +1131,34 @@ struct ncb {
#endif
/*
- ** A copy of the script, relocated for this ncb.
+ ** Scripts instance virtual address.
*/
struct script *script;
+ struct scripth *scripth;
/*
- ** Physical address of this instance of ncb->script
+ ** Scripts instance physical address.
*/
u_long p_script;
+ u_long p_scripth;
/*
** The SCSI address of the host adapter.
*/
- u_char myaddr;
+ u_char myaddr;
/*
** timing parameters
*/
- u_char ns_sync;
- u_char maxoffs;
+ u_char minsync; /* Minimum sync period factor */
+ u_char maxsync; /* Maximum sync period factor */
+ u_char maxoffs; /* Max scsi offset */
+ u_char clock_divn; /* Number of clock divisors */
+ u_long clock_khz; /* SCSI clock frequency in KHz */
+ u_long features; /* Chip features map */
+ u_char multiplier; /* Clock multiplier (1,2,4) */
+
+ u_char maxburst; /* log base 2 of dwords burst */
/*
** BIOS supplied PCI bus options
@@ -1090,7 +1167,10 @@ struct ncb {
u_char rv_dcntl;
u_char rv_dmode;
u_char rv_ctest3;
+ u_char rv_ctest4;
u_char rv_ctest5;
+ u_char rv_gpcntl;
+ u_char rv_stest2;
/*-----------------------------------------------
** Link to the generic SCSI driver
@@ -1116,7 +1196,7 @@ struct ncb {
/*
** Start queue.
*/
- u_long squeue [MAX_START];
+ u_int32_t squeue [MAX_START];
u_short squeueput;
u_short actccbs;
@@ -1127,6 +1207,9 @@ struct ncb {
u_short ticks;
u_short latetime;
u_long lasttime;
+#ifdef __FreeBSD__
+ struct callout_handle timeout_ch;
+#endif
/*-----------------------------------------------
** Debug and profiling
@@ -1145,19 +1228,14 @@ struct ncb {
u_long disc_ref;
/*
- ** The global header.
- ** Accessible to both the host and the
- ** script-processor.
- */
- struct head header;
-
- /*
** The global control block.
** It's used only during the configuration phase.
** A target control block will be created
** after the first successful transfer.
+ ** It is allocated separately in order to ensure
+ ** cache line size alignment.
*/
- struct ccb ccb;
+ struct ccb *ccb;
/*
** message buffers.
@@ -1167,7 +1245,7 @@ struct ncb {
*/
u_char msgout[8];
u_char msgin [8];
- u_long lastmsg;
+ u_int32_t lastmsg;
/*
** Buffer for STATUS_IN phase.
@@ -1184,7 +1262,7 @@ struct ncb {
*/
u_char disc;
-#if defined(NCR_IOMAPPED) && !(defined(__NetBSD__) || defined(__OpenBSD__))
+#if defined(NCR_IOMAPPED) && !defined(__OpenBSD__)
/*
** address of the ncr control registers in io space
*/
@@ -1193,6 +1271,7 @@ struct ncb {
};
#define NCB_SCRIPT_PHYS(np,lbl) (np->p_script + offsetof (struct script, lbl))
+#define NCB_SCRIPTH_PHYS(np,lbl) (np->p_scripth + offsetof (struct scripth,lbl))
/*==========================================================
**
@@ -1215,12 +1294,15 @@ struct ncb {
**----------------------------------------------------------
*/
+/*
+** Script fragments which are loaded into the on-board RAM
+** of 825A, 875 and 895 chips.
+*/
struct script {
ncrcmd start [ 7];
ncrcmd start0 [ 2];
ncrcmd start1 [ 3];
ncrcmd startpos [ 1];
- ncrcmd tryloop [MAX_START*5+2];
ncrcmd trysel [ 8];
ncrcmd skip [ 8];
ncrcmd skip2 [ 3];
@@ -1238,14 +1320,6 @@ struct script {
ncrcmd status [ 27];
ncrcmd msg_in [ 26];
ncrcmd msg_bad [ 6];
- ncrcmd msg_parity [ 6];
- ncrcmd msg_reject [ 8];
- ncrcmd msg_ign_residue [ 32];
- ncrcmd msg_extended [ 18];
- ncrcmd msg_ext_2 [ 18];
- ncrcmd msg_wdtr [ 27];
- ncrcmd msg_ext_3 [ 18];
- ncrcmd msg_sdtr [ 27];
ncrcmd complete [ 13];
ncrcmd cleanup [ 12];
ncrcmd cleanup0 [ 11];
@@ -1257,6 +1331,30 @@ struct script {
ncrcmd disconnect1 [ 23];
ncrcmd msg_out [ 9];
ncrcmd msg_out_done [ 7];
+ ncrcmd badgetcc [ 6];
+ ncrcmd reselect [ 8];
+ ncrcmd reselect1 [ 8];
+ ncrcmd reselect2 [ 8];
+ ncrcmd resel_tmp [ 5];
+ ncrcmd resel_lun [ 18];
+ ncrcmd resel_tag [ 24];
+ ncrcmd data_in [MAX_SCATTER * 4 + 7];
+ ncrcmd data_out [MAX_SCATTER * 4 + 7];
+};
+
+/*
+** Script fragments which stay in main memory for all chips.
+*/
+struct scripth {
+ ncrcmd tryloop [MAX_START*5+2];
+ ncrcmd msg_parity [ 6];
+ ncrcmd msg_reject [ 8];
+ ncrcmd msg_ign_residue [ 32];
+ ncrcmd msg_extended [ 18];
+ ncrcmd msg_ext_2 [ 18];
+ ncrcmd msg_wdtr [ 27];
+ ncrcmd msg_ext_3 [ 18];
+ ncrcmd msg_sdtr [ 27];
ncrcmd msg_out_abort [ 10];
ncrcmd getcc [ 4];
ncrcmd getcc1 [ 5];
@@ -1266,14 +1364,6 @@ struct script {
ncrcmd getcc2 [ 14];
#endif
ncrcmd getcc3 [ 10];
- ncrcmd badgetcc [ 6];
- ncrcmd reselect [ 12];
- ncrcmd reselect2 [ 6];
- ncrcmd resel_tmp [ 5];
- ncrcmd resel_lun [ 18];
- ncrcmd resel_tag [ 24];
- ncrcmd data_in [MAX_SCATTER * 4 + 7];
- ncrcmd data_out [MAX_SCATTER * 4 + 7];
ncrcmd aborttag [ 4];
ncrcmd abort [ 22];
ncrcmd snooptest [ 9];
@@ -1295,56 +1385,55 @@ static void ncr_complete (ncb_p np, ccb_p cp);
static int ncr_delta (struct timeval * from, struct timeval * to);
static void ncr_exception (ncb_p np);
static void ncr_free_ccb (ncb_p np, ccb_p cp, int flags);
-static void ncr_getclock (ncb_p np);
+static void ncr_selectclock (ncb_p np, u_char scntl3);
+static void ncr_getclock (ncb_p np, u_char multiplier);
static ccb_p ncr_get_ccb (ncb_p np, u_long flags, u_long t,u_long l);
static void ncr_init (ncb_p np, char * msg, u_long code);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
static int ncr_intr (void *vnp);
#else
static void ncr_intr (void *vnp);
-static U_INT32 ncr_info (int unit);
-#endif /* !(__NetBSD__ || __OpenBSD__) */
-static void ncr_int_ma (ncb_p np);
+static u_int32_t ncr_info (int unit);
+#endif /* !__OpenBSD__ */
+static void ncr_int_ma (ncb_p np, u_char dstat);
static void ncr_int_sir (ncb_p np);
static void ncr_int_sto (ncb_p np);
-#ifndef NEW_SCSICONF
+#ifdef __OpenBSD__
static u_long ncr_lookup (char* id);
-#endif /* NEW_SCSICONF */
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
-static void ncr_min_phys (struct buf *bp);
-#else
-static void ncr_minphys (struct buf *bp);
#endif
+static void ncr_min_phys (struct buf *bp);
static void ncr_negotiate (struct ncb* np, struct tcb* tp);
static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp);
static void ncb_profile (ncb_p np, ccb_p cp);
static void ncr_script_copy_and_bind
- (struct script * script, ncb_p np);
-static void ncr_script_fill (struct script * scr);
+ (ncb_p np, ncrcmd *src, ncrcmd *dst, int len);
+static void ncr_script_fill (struct script * scr, struct scripth *scrh);
static int ncr_scatter (struct dsb* phys, vm_offset_t vaddr,
vm_size_t datalen);
static void ncr_setmaxtags (tcb_p tp, u_long usrtags);
-static void ncr_setsync (ncb_p np, ccb_p cp, u_char sxfer);
-static void ncr_settags (tcb_p tp, lcb_p lp);
-static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide);
+static void ncr_getsync (ncb_p np, u_char sfac, u_char *fakp,
+ u_char *scntl3p);
+static void ncr_setsync (ncb_p np, ccb_p cp,u_char scntl3,u_char sxfer);
+static void ncr_settags (tcb_p tp, lcb_p lp, u_long usrtags);
+static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide, u_char ack);
static int ncr_show_msg (u_char * msg);
static int ncr_snooptest (ncb_p np);
-static INT32 ncr_start (struct scsi_xfer *xp);
-static void ncr_timeout (ncb_p np);
+static int32_t ncr_start (struct scsi_xfer *xp);
+static void ncr_timeout (void *arg);
static void ncr_usercmd (ncb_p np);
static void ncr_wakeup (ncb_p np, u_long code);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
#ifdef __BROKEN_INDIRECT_CONFIG
static int ncr_probe (struct device *, void *, void *);
#else
static int ncr_probe (struct device *, struct cfdata *, void *);
#endif
static void ncr_attach (struct device *, struct device *, void *);
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#else /* !__OpenBSD__ */
static char* ncr_probe (pcici_t tag, pcidi_t type);
static void ncr_attach (pcici_t tag, int unit);
-#endif /* __NetBSD__ || __OpenBSD__ */
+#endif /* __OpenBSD__ */
#endif /* KERNEL */
@@ -1360,7 +1449,7 @@ static void ncr_attach (pcici_t tag, int unit);
#if 0
static char ident[] =
- "\n$OpenBSD: ncr.c,v 1.31 1997/10/11 11:05:27 pefo Exp $\n";
+ "\n$OpenBSD: ncr.c,v 1.32 1997/12/01 18:58:48 millert Exp $\n";
#endif
static const u_long ncr_version = NCR_VERSION * 11
@@ -1371,15 +1460,15 @@ static const u_long ncr_version = NCR_VERSION * 11
#ifdef KERNEL
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+#ifndef __OpenBSD__
static const int nncr=MAX_UNITS; /* XXX to be replaced by SYSCTL */
ncb_p ncrp [MAX_UNITS]; /* XXX to be replaced by SYSCTL */
-#endif /* !(__NetBSD__ || __OpenBSD__) */
+#endif /* !__OpenBSD__ */
static int ncr_debug = SCSI_NCR_DEBUG;
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+#ifndef __OpenBSD__
SYSCTL_INT(_debug, OID_AUTO, ncr_debug, CTLFLAG_RW, &ncr_debug, 0, "");
-#endif /* !(__NetBSD__ || __OpenBSD__) */
+#endif /* !__OpenBSD__ */
static int ncr_cache; /* to be aligned _NOT_ static */
@@ -1394,11 +1483,16 @@ static int ncr_cache; /* to be aligned _NOT_ static */
#define NCR_810_ID (0x00011000ul)
#define NCR_815_ID (0x00041000ul)
+#define NCR_820_ID (0x00021000ul)
#define NCR_825_ID (0x00031000ul)
#define NCR_860_ID (0x00061000ul)
#define NCR_875_ID (0x000f1000ul)
+#define NCR_875_ID2 (0x008f1000ul)
+#define NCR_885_ID (0x000d1000ul)
+#define NCR_895_ID (0x000c1000ul)
+#define NCR_896_ID (0x000b1000ul)
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
struct cfattach ncr_ca = {
sizeof(struct ncb), ncr_probe, ncr_attach
@@ -1408,7 +1502,7 @@ struct cfdriver ncr_cd = {
NULL, "ncr", DV_DULL
};
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#else /* !__OpenBSD__ */
static u_long ncr_count;
@@ -1422,22 +1516,18 @@ static struct pci_device ncr_device = {
DATA_SET (pcidevice_set, ncr_device);
-#endif /* !(__NetBSD__ || __OpenBSD__) */
+#endif /* !__OpenBSD__ */
static struct scsi_adapter ncr_switch =
{
ncr_start,
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
ncr_min_phys,
-#else
- ncr_minphys,
-#endif
0,
0,
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+#ifndef __OpenBSD__
ncr_info,
"ncr",
-#endif /* !(__NetBSD__ || __OpenBSD__) */
+#endif /* !__OpenBSD__ */
};
static struct scsi_device ncr_dev =
@@ -1446,16 +1536,16 @@ static struct scsi_device ncr_dev =
NULL, /* have a queue, served by this */
NULL, /* have no async handler */
NULL, /* Use default 'done' routine */
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+#ifndef __OpenBSD__
"ncr",
-#endif /* !(__NetBSD__ || __OpenBSD__) */
+#endif /* !__OpenBSD__ */
};
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
#define ncr_name(np) (np->sc_dev.dv_xname)
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#else /* !__OpenBSD__ */
static char *ncr_name (ncb_p np)
{
@@ -1488,30 +1578,37 @@ static char *ncr_name (ncb_p np)
#define RELOC_LABEL 0x50000000
#define RELOC_REGISTER 0x60000000
#define RELOC_KVAR 0x70000000
+#define RELOC_LABELH 0x80000000
#define RELOC_MASK 0xf0000000
#define NADDR(label) (RELOC_SOFTC | offsetof(struct ncb, label))
#define PADDR(label) (RELOC_LABEL | offsetof(struct script, label))
+#define PADDRH(label) (RELOC_LABELH | offsetof(struct scripth, label))
#define RADDR(label) (RELOC_REGISTER | REG(label))
#define FADDR(label,ofs)(RELOC_REGISTER | ((REG(label))+(ofs)))
#define KVAR(which) (RELOC_KVAR | (which))
-#define SCRIPT_KVAR_MONO_TIME_TV_SEC (0)
-#define SCRIPT_KVAR_MONO_TIME (SCRIPT_KVAR_MONO_TIME_TV_SEC + 1)
-#define SCRIPT_KVAR_NCR_CACHE (SCRIPT_KVAR_MONO_TIME + 1)
+#define KVAR_TIME_TV_SEC (0)
+#define KVAR_TIME (1)
+#define KVAR_NCR_CACHE (2)
-#define SCRIPT_KVAR_FIRST SCRIPT_KVAR_MONO_TIME_TV_SEC
-#define SCRIPT_KVAR_LAST SCRIPT_KVAR_NCR_CACHE
+#define SCRIPT_KVAR_FIRST (0)
+#define SCRIPT_KVAR_LAST (3)
/*
* Kernel variables referenced in the scripts.
* THESE MUST ALL BE ALIGNED TO A 4-BYTE BOUNDARY.
*/
+#ifdef __OpenBSD__
static unsigned long script_kvars[] = {
(unsigned long)&mono_time.tv_sec,
(unsigned long)&mono_time,
(unsigned long)&ncr_cache,
};
+#else
+static void *script_kvars[] =
+ { &time.tv_sec, &time, &ncr_cache };
+#endif
static struct script script0 = {
/*--------------------------< START >-----------------------*/ {
@@ -1519,7 +1616,7 @@ static struct script script0 = {
** Claim to be still alive ...
*/
SCR_COPY (sizeof (((struct ncb *)0)->heartbeat)),
- KVAR(SCRIPT_KVAR_MONO_TIME_TV_SEC),
+ KVAR (KVAR_TIME_TV_SEC),
NADDR (heartbeat),
/*
** Make data structure address invalid.
@@ -1552,32 +1649,7 @@ static struct script script0 = {
*/
SCR_JUMP,
}/*-------------------------< STARTPOS >--------------------*/,{
- PADDR(tryloop),
-}/*-------------------------< TRYLOOP >---------------------*/,{
-/*
-** Load an entry of the start queue into dsa
-** and try to start it by jumping to TRYSEL.
-**
-** Because the size depends on the
-** #define MAX_START parameter, it is filled
-** in at runtime.
-**
-**-----------------------------------------------------------
-**
-** ##===========< I=0; i<MAX_START >===========
-** || SCR_COPY (4),
-** || NADDR (squeue[i]),
-** || RADDR (dsa),
-** || SCR_CALL,
-** || PADDR (trysel),
-** ##==========================================
-**
-** SCR_JUMP,
-** PADDR(tryloop),
-**
-**-----------------------------------------------------------
-*/
-0
+ PADDRH(tryloop),
}/*-------------------------< TRYSEL >----------------------*/,{
/*
@@ -1633,7 +1705,7 @@ static struct script script0 = {
** patch the launch field.
** should look like an idle process.
*/
- SCR_COPY (4),
+ SCR_COPY_F (4),
RADDR (dsa),
PADDR (skip2),
SCR_COPY (8),
@@ -1739,7 +1811,7 @@ static struct script script0 = {
** We patch the address part of a
** COPY command with the DSA-register.
*/
- SCR_COPY (4),
+ SCR_COPY_F (4),
RADDR (dsa),
PADDR (loadpos),
/*
@@ -1763,7 +1835,7 @@ static struct script script0 = {
** Set a time stamp for this selection
*/
SCR_COPY (sizeof (struct timeval)),
- KVAR(SCRIPT_KVAR_MONO_TIME),
+ KVAR (KVAR_TIME),
NADDR (header.stamp.select),
/*
** load the savep (saved pointer) into
@@ -1816,7 +1888,7 @@ static struct script script0 = {
SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),
PADDR (msg_in),
SCR_JUMP ^ IFTRUE (DATA (M_REJECT)),
- PADDR (msg_reject),
+ PADDRH (msg_reject),
/*
** normal processing
*/
@@ -1945,7 +2017,7 @@ static struct script script0 = {
** ... set a timestamp ...
*/
SCR_COPY (sizeof (struct timeval)),
- KVAR(SCRIPT_KVAR_MONO_TIME),
+ KVAR (KVAR_TIME),
NADDR (header.stamp.command),
/*
** ... and send the command
@@ -1967,7 +2039,7 @@ static struct script script0 = {
** set the timestamp.
*/
SCR_COPY (sizeof (struct timeval)),
- KVAR(SCRIPT_KVAR_MONO_TIME),
+ KVAR (KVAR_TIME),
NADDR (header.stamp.status),
/*
** If this is a GETCC transfer,
@@ -2033,7 +2105,7 @@ static struct script script0 = {
SCR_FROM_REG (socl),
0,
SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
- PADDR (msg_parity),
+ PADDRH (msg_parity),
SCR_FROM_REG (scratcha),
0,
/*
@@ -2048,13 +2120,13 @@ static struct script script0 = {
SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)),
PADDR (disconnect),
SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),
- PADDR (msg_extended),
+ PADDRH (msg_extended),
SCR_JUMP ^ IFTRUE (DATA (M_NOOP)),
PADDR (clrack),
SCR_JUMP ^ IFTRUE (DATA (M_REJECT)),
- PADDR (msg_reject),
+ PADDRH (msg_reject),
SCR_JUMP ^ IFTRUE (DATA (M_IGN_RESIDUE)),
- PADDR (msg_ign_residue),
+ PADDRH (msg_ign_residue),
/*
** Rest of the messages left as
** an exercise ...
@@ -2073,266 +2145,6 @@ static struct script script0 = {
SCR_JUMP,
PADDR (setmsg),
-}/*-------------------------< MSG_PARITY >---------------*/,{
- /*
- ** count it
- */
- SCR_REG_REG (PS_REG, SCR_ADD, 0x01),
- 0,
- /*
- ** send a "message parity error" message.
- */
- SCR_LOAD_REG (scratcha, M_PARITY),
- 0,
- SCR_JUMP,
- PADDR (setmsg),
-}/*-------------------------< MSG_REJECT >---------------*/,{
- /*
- ** If a negotiation was in progress,
- ** negotiation failed.
- */
- SCR_FROM_REG (HS_REG),
- 0,
- SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),
- SIR_NEGO_FAILED,
- /*
- ** else make host log this message
- */
- SCR_INT ^ IFFALSE (DATA (HS_NEGOTIATE)),
- SIR_REJECT_RECEIVED,
- SCR_JUMP,
- PADDR (clrack),
-
-}/*-------------------------< MSG_IGN_RESIDUE >----------*/,{
- /*
- ** Terminate cycle
- */
- SCR_CLR (SCR_ACK),
- 0,
- SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
- PADDR (dispatch),
- /*
- ** get residue size.
- */
- SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
- NADDR (msgin[1]),
- /*
- ** Check for message parity error.
- */
- SCR_TO_REG (scratcha),
- 0,
- SCR_FROM_REG (socl),
- 0,
- SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
- PADDR (msg_parity),
- SCR_FROM_REG (scratcha),
- 0,
- /*
- ** Size is 0 .. ignore message.
- */
- SCR_JUMP ^ IFTRUE (DATA (0)),
- PADDR (clrack),
- /*
- ** Size is not 1 .. have to interrupt.
- */
-/*<<<*/ SCR_JUMPR ^ IFFALSE (DATA (1)),
- 40,
- /*
- ** Check for residue byte in swide register
- */
- SCR_FROM_REG (scntl2),
- 0,
-/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)),
- 16,
- /*
- ** There IS data in the swide register.
- ** Discard it.
- */
- SCR_REG_REG (scntl2, SCR_OR, WSR),
- 0,
- SCR_JUMP,
- PADDR (clrack),
- /*
- ** Load again the size to the sfbr register.
- */
-/*>>>*/ SCR_FROM_REG (scratcha),
- 0,
-/*>>>*/ SCR_INT,
- SIR_IGN_RESIDUE,
- SCR_JUMP,
- PADDR (clrack),
-
-}/*-------------------------< MSG_EXTENDED >-------------*/,{
- /*
- ** Terminate cycle
- */
- SCR_CLR (SCR_ACK),
- 0,
- SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
- PADDR (dispatch),
- /*
- ** get length.
- */
- SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
- NADDR (msgin[1]),
- /*
- ** Check for message parity error.
- */
- SCR_TO_REG (scratcha),
- 0,
- SCR_FROM_REG (socl),
- 0,
- SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
- PADDR (msg_parity),
- SCR_FROM_REG (scratcha),
- 0,
- /*
- */
- SCR_JUMP ^ IFTRUE (DATA (3)),
- PADDR (msg_ext_3),
- SCR_JUMP ^ IFFALSE (DATA (2)),
- PADDR (msg_bad),
-}/*-------------------------< MSG_EXT_2 >----------------*/,{
- SCR_CLR (SCR_ACK),
- 0,
- SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
- PADDR (dispatch),
- /*
- ** get extended message code.
- */
- SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
- NADDR (msgin[2]),
- /*
- ** Check for message parity error.
- */
- SCR_TO_REG (scratcha),
- 0,
- SCR_FROM_REG (socl),
- 0,
- SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
- PADDR (msg_parity),
- SCR_FROM_REG (scratcha),
- 0,
- SCR_JUMP ^ IFTRUE (DATA (M_X_WIDE_REQ)),
- PADDR (msg_wdtr),
- /*
- ** unknown extended message
- */
- SCR_JUMP,
- PADDR (msg_bad)
-}/*-------------------------< MSG_WDTR >-----------------*/,{
- SCR_CLR (SCR_ACK),
- 0,
- SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
- PADDR (dispatch),
- /*
- ** get data bus width
- */
- SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
- NADDR (msgin[3]),
- SCR_FROM_REG (socl),
- 0,
- SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
- PADDR (msg_parity),
- /*
- ** let the host do the real work.
- */
- SCR_INT,
- SIR_NEGO_WIDE,
- /*
- ** let the target fetch our answer.
- */
- SCR_SET (SCR_ATN),
- 0,
- SCR_CLR (SCR_ACK),
- 0,
-
- SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
- SIR_NEGO_PROTO,
- /*
- ** Send the M_X_WIDE_REQ
- */
- SCR_MOVE_ABS (4) ^ SCR_MSG_OUT,
- NADDR (msgout),
- SCR_CLR (SCR_ATN),
- 0,
- SCR_COPY (1),
- RADDR (sfbr),
- NADDR (lastmsg),
- SCR_JUMP,
- PADDR (msg_out_done),
-
-}/*-------------------------< MSG_EXT_3 >----------------*/,{
- SCR_CLR (SCR_ACK),
- 0,
- SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
- PADDR (dispatch),
- /*
- ** get extended message code.
- */
- SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
- NADDR (msgin[2]),
- /*
- ** Check for message parity error.
- */
- SCR_TO_REG (scratcha),
- 0,
- SCR_FROM_REG (socl),
- 0,
- SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
- PADDR (msg_parity),
- SCR_FROM_REG (scratcha),
- 0,
- SCR_JUMP ^ IFTRUE (DATA (M_X_SYNC_REQ)),
- PADDR (msg_sdtr),
- /*
- ** unknown extended message
- */
- SCR_JUMP,
- PADDR (msg_bad)
-
-}/*-------------------------< MSG_SDTR >-----------------*/,{
- SCR_CLR (SCR_ACK),
- 0,
- SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
- PADDR (dispatch),
- /*
- ** get period and offset
- */
- SCR_MOVE_ABS (2) ^ SCR_MSG_IN,
- NADDR (msgin[3]),
- SCR_FROM_REG (socl),
- 0,
- SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
- PADDR (msg_parity),
- /*
- ** let the host do the real work.
- */
- SCR_INT,
- SIR_NEGO_SYNC,
- /*
- ** let the target fetch our answer.
- */
- SCR_SET (SCR_ATN),
- 0,
- SCR_CLR (SCR_ACK),
- 0,
-
- SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
- SIR_NEGO_PROTO,
- /*
- ** Send the M_X_SYNC_REQ
- */
- SCR_MOVE_ABS (5) ^ SCR_MSG_OUT,
- NADDR (msgout),
- SCR_CLR (SCR_ATN),
- 0,
- SCR_COPY (1),
- RADDR (sfbr),
- NADDR (lastmsg),
- SCR_JUMP,
- PADDR (msg_out_done),
-
}/*-------------------------< COMPLETE >-----------------*/,{
/*
** Complete message.
@@ -2388,7 +2200,7 @@ static struct script script0 = {
/*
** and copy back the header to the ccb.
*/
- SCR_COPY (4),
+ SCR_COPY_F (4),
RADDR (dsa),
PADDR (cleanup0),
SCR_COPY (sizeof (struct head)),
@@ -2408,7 +2220,7 @@ static struct script script0 = {
SCR_FROM_REG (SS_REG),
0,
SCR_JUMP ^ IFTRUE (DATA (S_CHECK_COND)),
- PADDR(getcc2),
+ PADDRH(getcc2),
/*
** And make the DSA register invalid.
*/
@@ -2494,7 +2306,7 @@ static struct script script0 = {
**
** CAUTION: only little endian architectures supported! XXX
*/
- SCR_COPY (1),
+ SCR_COPY_F (1),
NADDR (header.savep),
PADDR (disconnect0),
}/*-------------------------< DISCONNECT0 >--------------*/,{
@@ -2503,7 +2315,7 @@ static struct script script0 = {
/*
** neither this
*/
- SCR_COPY (1),
+ SCR_COPY_F (1),
NADDR (header.goalp),
PADDR (disconnect1),
}/*-------------------------< DISCONNECT1 >--------------*/,{
@@ -2532,7 +2344,7 @@ static struct script script0 = {
** and count the disconnects.
*/
SCR_COPY (sizeof (struct timeval)),
- KVAR(SCRIPT_KVAR_MONO_TIME),
+ KVAR (KVAR_TIME),
NADDR (header.stamp.disconnect),
SCR_COPY (4),
NADDR (disc_phys),
@@ -2563,7 +2375,7 @@ static struct script script0 = {
** If it was no ABORT message ...
*/
SCR_JUMP ^ IFTRUE (DATA (M_ABORT)),
- PADDR (msg_out_abort),
+ PADDRH (msg_out_abort),
/*
** ... wait for the next phase
** if it's a message out, send it again, ...
@@ -2584,167 +2396,6 @@ static struct script script0 = {
*/
SCR_JUMP,
PADDR (dispatch),
-}/*-------------------------< MSG_OUT_ABORT >-------------*/,{
- /*
- ** After ABORT message,
- **
- ** expect an immediate disconnect, ...
- */
- SCR_REG_REG (scntl2, SCR_AND, 0x7f),
- 0,
- SCR_CLR (SCR_ACK|SCR_ATN),
- 0,
- SCR_WAIT_DISC,
- 0,
- /*
- ** ... and set the status to "ABORTED"
- */
- SCR_LOAD_REG (HS_REG, HS_ABORTED),
- 0,
- SCR_JUMP,
- PADDR (cleanup),
-
-}/*-------------------------< GETCC >-----------------------*/,{
- /*
- ** The ncr doesn't have an indirect load
- ** or store command. So we have to
- ** copy part of the control block to a
- ** fixed place, where we can modify it.
- **
- ** We patch the address part of a COPY command
- ** with the address of the dsa register ...
- */
- SCR_COPY (4),
- RADDR (dsa),
- PADDR (getcc1),
- /*
- ** ... then we do the actual copy.
- */
- SCR_COPY (sizeof (struct head)),
-}/*-------------------------< GETCC1 >----------------------*/,{
- 0,
- NADDR (header),
- /*
- ** Initialize the status registers
- */
- SCR_COPY (4),
- NADDR (header.status),
- RADDR (scr0),
-}/*-------------------------< GETCC2 >----------------------*/,{
- /*
- ** Get the condition code from a target.
- **
- ** DSA points to a data structure.
- ** Set TEMP to the script location
- ** that receives the condition code.
- **
- ** Because there is no script command
- ** to load a longword into a register,
- ** we use a CALL command.
- */
-/*<<<*/ SCR_CALLR,
- 24,
- /*
- ** Get the condition code.
- */
- SCR_MOVE_TBL ^ SCR_DATA_IN,
- offsetof (struct dsb, sense),
- /*
- ** No data phase may follow!
- */
- SCR_CALL,
- PADDR (checkatn),
- SCR_JUMP,
- PADDR (no_data),
-/*>>>*/
-
- /*
- ** The CALL jumps to this point.
- ** Prepare for a RESTORE_POINTER message.
- ** Save the TEMP register into the saved pointer.
- */
- SCR_COPY (4),
- RADDR (temp),
- NADDR (header.savep),
- /*
- ** Load scratcha, because in case of a selection timeout,
- ** the host will expect a new value for startpos in
- ** the scratcha register.
- */
- SCR_COPY (4),
- PADDR (startpos),
- RADDR (scratcha),
-#ifdef NCR_GETCC_WITHMSG
- /*
- ** If QUIRK_NOMSG is set, select without ATN.
- ** and don't send a message.
- */
- SCR_FROM_REG (QU_REG),
- 0,
- SCR_JUMP ^ IFTRUE (MASK (QUIRK_NOMSG, QUIRK_NOMSG)),
- PADDR(getcc3),
- /*
- ** Then try to connect to the target.
- ** If we are reselected, special treatment
- ** of the current job is required before
- ** accepting the reselection.
- */
- SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select),
- PADDR(badgetcc),
- /*
- ** save target id.
- */
- SCR_FROM_REG (sdid),
- 0,
- SCR_TO_REG (ctest0),
- 0,
- /*
- ** Send the IDENTIFY message.
- ** In case of short transfer, remove ATN.
- */
- SCR_MOVE_TBL ^ SCR_MSG_OUT,
- offsetof (struct dsb, smsg2),
- SCR_CLR (SCR_ATN),
- 0,
- /*
- ** save the first byte of the message.
- */
- SCR_COPY (1),
- RADDR (sfbr),
- NADDR (lastmsg),
- SCR_JUMP,
- PADDR (prepare2),
-
-#endif
-}/*-------------------------< GETCC3 >----------------------*/,{
- /*
- ** Try to connect to the target.
- ** If we are reselected, special treatment
- ** of the current job is required before
- ** accepting the reselection.
- **
- ** Silly target won't accept a message.
- ** Select without ATN.
- */
- SCR_SEL_TBL ^ offsetof (struct dsb, select),
- PADDR(badgetcc),
- /*
- ** save target id.
- */
- SCR_FROM_REG (sdid),
- 0,
- SCR_TO_REG (ctest0),
- 0,
- /*
- ** Force error if selection timeout
- */
- SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)),
- 0,
- /*
- ** don't negotiate.
- */
- SCR_JUMP,
- PADDR (prepare2),
}/*------------------------< BADGETCC >---------------------*/,{
/*
@@ -2753,11 +2404,18 @@ static struct script script0 = {
SCR_FROM_REG (ctest2),
0,
SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)),
- PADDR (getcc2),
+ PADDRH (getcc2),
SCR_INT,
SIR_SENSE_FAILED,
}/*-------------------------< RESELECT >--------------------*/,{
/*
+ ** This NOP will be patched with LED OFF
+ ** SCR_REG_REG (gpreg, SCR_OR, 0x01)
+ */
+ SCR_NO_OP,
+ 0,
+
+ /*
** make the DSA invalid.
*/
SCR_LOAD_REG (dsa, 0xff),
@@ -2772,6 +2430,13 @@ static struct script script0 = {
*/
SCR_WAIT_RESEL,
PADDR(reselect2),
+}/*-------------------------< RESELECT1 >--------------------*/,{
+ /*
+ ** This NOP will be patched with LED ON
+ ** SCR_REG_REG (gpreg, SCR_AND, 0xfe)
+ */
+ SCR_NO_OP,
+ 0,
/*
** ... zu nichts zu gebrauchen ?
**
@@ -2793,6 +2458,12 @@ static struct script script0 = {
NADDR (jump_tcb),
}/*-------------------------< RESELECT2 >-------------------*/,{
/*
+ ** This NOP will be patched with LED ON
+ ** SCR_REG_REG (gpreg, SCR_AND, 0xfe)
+ */
+ SCR_NO_OP,
+ 0,
+ /*
** If it's not connected :(
** -> interrupted by SIGP bit.
** Jump to start.
@@ -2916,7 +2587,7 @@ static struct script script0 = {
** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),
** PADDR (no_data),
** SCR_COPY (sizeof (struct timeval)),
-** KVAR(SCRIPT_KVAR_MONO_TIME),
+** KVAR (KVAR_TIME),
** NADDR (header.stamp.data),
** SCR_MOVE_TBL ^ SCR_DATA_IN,
** offsetof (struct dsb, data[ 0]),
@@ -2940,10 +2611,10 @@ static struct script script0 = {
** #define MAX_SCATTER parameter,
** it is filled in at runtime.
**
-** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),
+** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_OUT)),
** PADDR (no_data),
** SCR_COPY (sizeof (struct timeval)),
-** KVAR(SCRIPT_KVAR_MONO_TIME),
+** KVAR (KVAR_TIME),
** NADDR (header.stamp.data),
** SCR_MOVE_TBL ^ SCR_DATA_OUT,
** offsetof (struct dsb, data[ 0]),
@@ -2962,7 +2633,463 @@ static struct script script0 = {
**
**---------------------------------------------------------
*/
+#ifdef __OpenBSD__
0
+#else
+(u_long)&ident
+#endif
+
+}/*--------------------------------------------------------*/
+};
+
+
+static struct scripth scripth0 = {
+/*-------------------------< TRYLOOP >---------------------*/{
+/*
+** Load an entry of the start queue into dsa
+** and try to start it by jumping to TRYSEL.
+**
+** Because the size depends on the
+** #define MAX_START parameter, it is filled
+** in at runtime.
+**
+**-----------------------------------------------------------
+**
+** ##===========< I=0; i<MAX_START >===========
+** || SCR_COPY (4),
+** || NADDR (squeue[i]),
+** || RADDR (dsa),
+** || SCR_CALL,
+** || PADDR (trysel),
+** ##==========================================
+**
+** SCR_JUMP,
+** PADDRH(tryloop),
+**
+**-----------------------------------------------------------
+*/
+0
+}/*-------------------------< MSG_PARITY >---------------*/,{
+ /*
+ ** count it
+ */
+ SCR_REG_REG (PS_REG, SCR_ADD, 0x01),
+ 0,
+ /*
+ ** send a "message parity error" message.
+ */
+ SCR_LOAD_REG (scratcha, M_PARITY),
+ 0,
+ SCR_JUMP,
+ PADDR (setmsg),
+}/*-------------------------< MSG_REJECT >---------------*/,{
+ /*
+ ** If a negotiation was in progress,
+ ** negotiation failed.
+ */
+ SCR_FROM_REG (HS_REG),
+ 0,
+ SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),
+ SIR_NEGO_FAILED,
+ /*
+ ** else make host log this message
+ */
+ SCR_INT ^ IFFALSE (DATA (HS_NEGOTIATE)),
+ SIR_REJECT_RECEIVED,
+ SCR_JUMP,
+ PADDR (clrack),
+
+}/*-------------------------< MSG_IGN_RESIDUE >----------*/,{
+ /*
+ ** Terminate cycle
+ */
+ SCR_CLR (SCR_ACK),
+ 0,
+ SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
+ PADDR (dispatch),
+ /*
+ ** get residue size.
+ */
+ SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
+ NADDR (msgin[1]),
+ /*
+ ** Check for message parity error.
+ */
+ SCR_TO_REG (scratcha),
+ 0,
+ SCR_FROM_REG (socl),
+ 0,
+ SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
+ PADDRH (msg_parity),
+ SCR_FROM_REG (scratcha),
+ 0,
+ /*
+ ** Size is 0 .. ignore message.
+ */
+ SCR_JUMP ^ IFTRUE (DATA (0)),
+ PADDR (clrack),
+ /*
+ ** Size is not 1 .. have to interrupt.
+ */
+/*<<<*/ SCR_JUMPR ^ IFFALSE (DATA (1)),
+ 40,
+ /*
+ ** Check for residue byte in swide register
+ */
+ SCR_FROM_REG (scntl2),
+ 0,
+/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)),
+ 16,
+ /*
+ ** There IS data in the swide register.
+ ** Discard it.
+ */
+ SCR_REG_REG (scntl2, SCR_OR, WSR),
+ 0,
+ SCR_JUMP,
+ PADDR (clrack),
+ /*
+ ** Load again the size to the sfbr register.
+ */
+/*>>>*/ SCR_FROM_REG (scratcha),
+ 0,
+/*>>>*/ SCR_INT,
+ SIR_IGN_RESIDUE,
+ SCR_JUMP,
+ PADDR (clrack),
+
+}/*-------------------------< MSG_EXTENDED >-------------*/,{
+ /*
+ ** Terminate cycle
+ */
+ SCR_CLR (SCR_ACK),
+ 0,
+ SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
+ PADDR (dispatch),
+ /*
+ ** get length.
+ */
+ SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
+ NADDR (msgin[1]),
+ /*
+ ** Check for message parity error.
+ */
+ SCR_TO_REG (scratcha),
+ 0,
+ SCR_FROM_REG (socl),
+ 0,
+ SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
+ PADDRH (msg_parity),
+ SCR_FROM_REG (scratcha),
+ 0,
+ /*
+ */
+ SCR_JUMP ^ IFTRUE (DATA (3)),
+ PADDRH (msg_ext_3),
+ SCR_JUMP ^ IFFALSE (DATA (2)),
+ PADDR (msg_bad),
+}/*-------------------------< MSG_EXT_2 >----------------*/,{
+ SCR_CLR (SCR_ACK),
+ 0,
+ SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
+ PADDR (dispatch),
+ /*
+ ** get extended message code.
+ */
+ SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
+ NADDR (msgin[2]),
+ /*
+ ** Check for message parity error.
+ */
+ SCR_TO_REG (scratcha),
+ 0,
+ SCR_FROM_REG (socl),
+ 0,
+ SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
+ PADDRH (msg_parity),
+ SCR_FROM_REG (scratcha),
+ 0,
+ SCR_JUMP ^ IFTRUE (DATA (M_X_WIDE_REQ)),
+ PADDRH (msg_wdtr),
+ /*
+ ** unknown extended message
+ */
+ SCR_JUMP,
+ PADDR (msg_bad)
+}/*-------------------------< MSG_WDTR >-----------------*/,{
+ SCR_CLR (SCR_ACK),
+ 0,
+ SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
+ PADDR (dispatch),
+ /*
+ ** get data bus width
+ */
+ SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
+ NADDR (msgin[3]),
+ SCR_FROM_REG (socl),
+ 0,
+ SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
+ PADDRH (msg_parity),
+ /*
+ ** let the host do the real work.
+ */
+ SCR_INT,
+ SIR_NEGO_WIDE,
+ /*
+ ** let the target fetch our answer.
+ */
+ SCR_SET (SCR_ATN),
+ 0,
+ SCR_CLR (SCR_ACK),
+ 0,
+
+ SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
+ SIR_NEGO_PROTO,
+ /*
+ ** Send the M_X_WIDE_REQ
+ */
+ SCR_MOVE_ABS (4) ^ SCR_MSG_OUT,
+ NADDR (msgout),
+ SCR_CLR (SCR_ATN),
+ 0,
+ SCR_COPY (1),
+ RADDR (sfbr),
+ NADDR (lastmsg),
+ SCR_JUMP,
+ PADDR (msg_out_done),
+
+}/*-------------------------< MSG_EXT_3 >----------------*/,{
+ SCR_CLR (SCR_ACK),
+ 0,
+ SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
+ PADDR (dispatch),
+ /*
+ ** get extended message code.
+ */
+ SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
+ NADDR (msgin[2]),
+ /*
+ ** Check for message parity error.
+ */
+ SCR_TO_REG (scratcha),
+ 0,
+ SCR_FROM_REG (socl),
+ 0,
+ SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
+ PADDRH (msg_parity),
+ SCR_FROM_REG (scratcha),
+ 0,
+ SCR_JUMP ^ IFTRUE (DATA (M_X_SYNC_REQ)),
+ PADDRH (msg_sdtr),
+ /*
+ ** unknown extended message
+ */
+ SCR_JUMP,
+ PADDR (msg_bad)
+
+}/*-------------------------< MSG_SDTR >-----------------*/,{
+ SCR_CLR (SCR_ACK),
+ 0,
+ SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
+ PADDR (dispatch),
+ /*
+ ** get period and offset
+ */
+ SCR_MOVE_ABS (2) ^ SCR_MSG_IN,
+ NADDR (msgin[3]),
+ SCR_FROM_REG (socl),
+ 0,
+ SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
+ PADDRH (msg_parity),
+ /*
+ ** let the host do the real work.
+ */
+ SCR_INT,
+ SIR_NEGO_SYNC,
+ /*
+ ** let the target fetch our answer.
+ */
+ SCR_SET (SCR_ATN),
+ 0,
+ SCR_CLR (SCR_ACK),
+ 0,
+
+ SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
+ SIR_NEGO_PROTO,
+ /*
+ ** Send the M_X_SYNC_REQ
+ */
+ SCR_MOVE_ABS (5) ^ SCR_MSG_OUT,
+ NADDR (msgout),
+ SCR_CLR (SCR_ATN),
+ 0,
+ SCR_COPY (1),
+ RADDR (sfbr),
+ NADDR (lastmsg),
+ SCR_JUMP,
+ PADDR (msg_out_done),
+
+}/*-------------------------< MSG_OUT_ABORT >-------------*/,{
+ /*
+ ** After ABORT message,
+ **
+ ** expect an immediate disconnect, ...
+ */
+ SCR_REG_REG (scntl2, SCR_AND, 0x7f),
+ 0,
+ SCR_CLR (SCR_ACK|SCR_ATN),
+ 0,
+ SCR_WAIT_DISC,
+ 0,
+ /*
+ ** ... and set the status to "ABORTED"
+ */
+ SCR_LOAD_REG (HS_REG, HS_ABORTED),
+ 0,
+ SCR_JUMP,
+ PADDR (cleanup),
+
+}/*-------------------------< GETCC >-----------------------*/,{
+ /*
+ ** The ncr doesn't have an indirect load
+ ** or store command. So we have to
+ ** copy part of the control block to a
+ ** fixed place, where we can modify it.
+ **
+ ** We patch the address part of a COPY command
+ ** with the address of the dsa register ...
+ */
+ SCR_COPY_F (4),
+ RADDR (dsa),
+ PADDRH (getcc1),
+ /*
+ ** ... then we do the actual copy.
+ */
+ SCR_COPY (sizeof (struct head)),
+}/*-------------------------< GETCC1 >----------------------*/,{
+ 0,
+ NADDR (header),
+ /*
+ ** Initialize the status registers
+ */
+ SCR_COPY (4),
+ NADDR (header.status),
+ RADDR (scr0),
+}/*-------------------------< GETCC2 >----------------------*/,{
+ /*
+ ** Get the condition code from a target.
+ **
+ ** DSA points to a data structure.
+ ** Set TEMP to the script location
+ ** that receives the condition code.
+ **
+ ** Because there is no script command
+ ** to load a longword into a register,
+ ** we use a CALL command.
+ */
+/*<<<*/ SCR_CALLR,
+ 24,
+ /*
+ ** Get the condition code.
+ */
+ SCR_MOVE_TBL ^ SCR_DATA_IN,
+ offsetof (struct dsb, sense),
+ /*
+ ** No data phase may follow!
+ */
+ SCR_CALL,
+ PADDR (checkatn),
+ SCR_JUMP,
+ PADDR (no_data),
+/*>>>*/
+
+ /*
+ ** The CALL jumps to this point.
+ ** Prepare for a RESTORE_POINTER message.
+ ** Save the TEMP register into the saved pointer.
+ */
+ SCR_COPY (4),
+ RADDR (temp),
+ NADDR (header.savep),
+ /*
+ ** Load scratcha, because in case of a selection timeout,
+ ** the host will expect a new value for startpos in
+ ** the scratcha register.
+ */
+ SCR_COPY (4),
+ PADDR (startpos),
+ RADDR (scratcha),
+#ifdef NCR_GETCC_WITHMSG
+ /*
+ ** If QUIRK_NOMSG is set, select without ATN.
+ ** and don't send a message.
+ */
+ SCR_FROM_REG (QU_REG),
+ 0,
+ SCR_JUMP ^ IFTRUE (MASK (QUIRK_NOMSG, QUIRK_NOMSG)),
+ PADDRH(getcc3),
+ /*
+ ** Then try to connect to the target.
+ ** If we are reselected, special treatment
+ ** of the current job is required before
+ ** accepting the reselection.
+ */
+ SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select),
+ PADDR(badgetcc),
+ /*
+ ** save target id.
+ */
+ SCR_FROM_REG (sdid),
+ 0,
+ SCR_TO_REG (ctest0),
+ 0,
+ /*
+ ** Send the IDENTIFY message.
+ ** In case of short transfer, remove ATN.
+ */
+ SCR_MOVE_TBL ^ SCR_MSG_OUT,
+ offsetof (struct dsb, smsg2),
+ SCR_CLR (SCR_ATN),
+ 0,
+ /*
+ ** save the first byte of the message.
+ */
+ SCR_COPY (1),
+ RADDR (sfbr),
+ NADDR (lastmsg),
+ SCR_JUMP,
+ PADDR (prepare2),
+
+#endif
+}/*-------------------------< GETCC3 >----------------------*/,{
+ /*
+ ** Try to connect to the target.
+ ** If we are reselected, special treatment
+ ** of the current job is required before
+ ** accepting the reselection.
+ **
+ ** Silly target won't accept a message.
+ ** Select without ATN.
+ */
+ SCR_SEL_TBL ^ offsetof (struct dsb, select),
+ PADDR(badgetcc),
+ /*
+ ** save target id.
+ */
+ SCR_FROM_REG (sdid),
+ 0,
+ SCR_TO_REG (ctest0),
+ 0,
+ /*
+ ** Force error if selection timeout
+ */
+ SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)),
+ 0,
+ /*
+ ** don't negotiate.
+ */
+ SCR_JUMP,
+ PADDR (prepare2),
}/*-------------------------< ABORTTAG >-------------------*/,{
/*
** Abort a bad reselection.
@@ -3004,19 +3131,19 @@ static struct script script0 = {
** Read the variable.
*/
SCR_COPY (4),
- KVAR(SCRIPT_KVAR_NCR_CACHE),
+ KVAR (KVAR_NCR_CACHE),
RADDR (scratcha),
/*
** Write the variable.
*/
SCR_COPY (4),
RADDR (temp),
- KVAR(SCRIPT_KVAR_NCR_CACHE),
+ KVAR (KVAR_NCR_CACHE),
/*
** Read back the variable.
*/
SCR_COPY (4),
- KVAR(SCRIPT_KVAR_NCR_CACHE),
+ KVAR (KVAR_NCR_CACHE),
RADDR (temp),
}/*-------------------------< SNOOPEND >-------------------*/,{
/*
@@ -3027,6 +3154,7 @@ static struct script script0 = {
}/*--------------------------------------------------------*/
};
+
/*==========================================================
**
**
@@ -3036,12 +3164,12 @@ static struct script script0 = {
**==========================================================
*/
-void ncr_script_fill (struct script * scr)
+void ncr_script_fill (struct script * scr, struct scripth * scrh)
{
int i;
ncrcmd *p;
- p = scr->tryloop;
+ p = scrh->tryloop;
for (i=0; i<MAX_START; i++) {
*p++ =SCR_COPY (4);
*p++ =NADDR (squeue[i]);
@@ -3050,16 +3178,16 @@ void ncr_script_fill (struct script * scr)
*p++ =PADDR (trysel);
};
*p++ =SCR_JUMP;
- *p++ =PADDR(tryloop);
+ *p++ =PADDRH(tryloop);
- assert ((u_long)p == (u_long)&scr->tryloop + sizeof (scr->tryloop));
+ assert ((u_long)p == (u_long)&scrh->tryloop + sizeof (scrh->tryloop));
p = scr->data_in;
*p++ =SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN));
*p++ =PADDR (no_data);
*p++ =SCR_COPY (sizeof (struct timeval));
- *p++ =KVAR(SCRIPT_KVAR_MONO_TIME);
+ *p++ =(ncrcmd) KVAR (KVAR_TIME);
*p++ =NADDR (header.stamp.data);
*p++ =SCR_MOVE_TBL ^ SCR_DATA_IN;
*p++ =offsetof (struct dsb, data[ 0]);
@@ -3083,7 +3211,7 @@ void ncr_script_fill (struct script * scr)
*p++ =SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_OUT));
*p++ =PADDR (no_data);
*p++ =SCR_COPY (sizeof (struct timeval));
- *p++ =KVAR(SCRIPT_KVAR_MONO_TIME);
+ *p++ =(ncrcmd) KVAR (KVAR_TIME);
*p++ =NADDR (header.stamp.data);
*p++ =SCR_MOVE_TBL ^ SCR_DATA_OUT;
*p++ =offsetof (struct dsb, data[ 0]);
@@ -3112,32 +3240,21 @@ void ncr_script_fill (struct script * scr)
**==========================================================
*/
-static void ncr_script_copy_and_bind (struct script *script, ncb_p np)
+static void ncr_script_copy_and_bind (ncb_p np, ncrcmd *src, ncrcmd *dst, int len)
{
ncrcmd opcode, new, old, tmp1, tmp2;
- ncrcmd *src, *dst, *start, *end;
- int relocs;
-
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
- np->script = (struct script*) vm_page_alloc_contig
- (round_page(sizeof (struct script)), 0x100000, 0xffffffff, PAGE_SIZE);
-#else /* !(__NetBSD__ || __OpenBSD__) */
- np->script = (struct script *)
- malloc (sizeof (struct script), M_DEVBUF, M_WAITOK);
-#endif /* __NetBSD__ || __OpenBSD__ */
-
- np->p_script = vtophys(np->script);
-
- src = script->start;
- dst = np->script->start;
+ ncrcmd *start, *end;
+ int relocs, offset;
start = src;
- end = src + (sizeof (struct script) / 4);
+ end = src + len/4;
+ offset = 0;
while (src < end) {
opcode = *src++;
- *dst++ = SCR_BO(opcode);
+ WRITESCRIPT_OFF(dst, offset, opcode);
+ offset += 4;
/*
** If we forget to change the length
@@ -3153,7 +3270,8 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np)
};
if (DEBUG_FLAGS & DEBUG_SCRIPT)
- printf ("%p: <%x>\n", (src-1), (unsigned)opcode);
+ printf ("%p: <%x>\n",
+ (src-1), (unsigned)opcode);
/*
** We don't have to decode ALL commands
@@ -3175,7 +3293,14 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np)
printf ("%s: ERROR1 IN SCRIPT at %ld.\n",
ncr_name(np), (long)(src-start-1));
DELAY (1000000);
- };
+ }
+ /*
+ ** If PREFETCH feature not enabled, remove
+ ** the NO FLUSH bit if present.
+ */
+ if ((opcode & SCR_NO_FLUSH) && !(np->features&FE_PFEN))
+ WRITESCRIPT_OFF(dst, offset - 4,
+ (opcode & ~SCR_NO_FLUSH));
break;
case 0x0:
@@ -3219,6 +3344,9 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np)
case RELOC_LABEL:
new = (old & ~RELOC_MASK) + np->p_script;
break;
+ case RELOC_LABELH:
+ new = (old & ~RELOC_MASK) + np->p_scripth;
+ break;
case RELOC_SOFTC:
new = (old & ~RELOC_MASK) + vtophys(np);
break;
@@ -3239,17 +3367,18 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np)
}
/* fall through */
default:
- panic("ncr_script_copy_and_bind: weird relocation %x\n", old);
+ panic("ncr_script_copy_and_bind: weird relocation %x @ %ld\n", old, (long)(src - start));
break;
}
- *dst++ = SCR_BO(new);
+ WRITESCRIPT_OFF(dst, offset, new);
+ offset += 4;
}
+ } else {
+ WRITESCRIPT_OFF(dst, offset, *src++);
+ offset += 4;
}
- else {
- *dst++ = SCR_BO(*src);
- src++;
- }
+
};
}
@@ -3277,15 +3406,15 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np)
**----------------------------------------------------------
*/
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+#ifndef __OpenBSD__
void ncr_min_phys (struct buf *bp)
{
if ((unsigned long)bp->b_bcount > MAX_SIZE) bp->b_bcount = MAX_SIZE;
}
#else
-void ncr_minphys (struct buf *bp)
+void ncr_min_phys (struct buf *bp)
{
- if(bp->b_bcount > MAX_SIZE)
+ if (bp->b_bcount > MAX_SIZE)
bp->b_bcount = MAX_SIZE;
minphys(bp);
}
@@ -3298,8 +3427,8 @@ void ncr_minphys (struct buf *bp)
**----------------------------------------------------------
*/
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
-U_INT32 ncr_info (int unit)
+#ifndef __OpenBSD__
+u_int32_t ncr_info (int unit)
{
return (1); /* may be changed later */
}
@@ -3307,12 +3436,89 @@ U_INT32 ncr_info (int unit)
/*----------------------------------------------------------
**
+** NCR chip devices table and chip look up function.
+** Features bit are defined in ncrreg.h. Is it the
+** right place?
+**
+**----------------------------------------------------------
+*/
+typedef struct {
+ unsigned long device_id;
+ unsigned short minrevid;
+ char *name;
+ unsigned char maxburst;
+ unsigned char maxoffs;
+ unsigned char clock_divn;
+ unsigned int features;
+} ncr_chip;
+
+static ncr_chip ncr_chip_table[] = {
+ {NCR_810_ID, 0x00, "ncr 53c810 fast10 scsi", 4, 8, 4,
+ FE_ERL}
+ ,
+ {NCR_810_ID, 0x10, "ncr 53c810a fast10 scsi", 4, 8, 4,
+ FE_ERL|FE_LDSTR|FE_PFEN|FE_BOF}
+ ,
+ {NCR_815_ID, 0x00, "ncr 53c815 fast10 scsi", 4, 8, 4,
+ FE_ERL|FE_BOF}
+ ,
+ {NCR_820_ID, 0x00, "ncr 53c820 fast10 wide scsi", 4, 8, 4,
+ FE_WIDE|FE_ERL}
+ ,
+ {NCR_825_ID, 0x00, "ncr 53c825 fast10 wide scsi", 4, 8, 4,
+ FE_WIDE|FE_ERL|FE_BOF}
+ ,
+ {NCR_825_ID, 0x10, "ncr 53c825a fast10 wide scsi", 7, 8, 4,
+ FE_WIDE|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
+ ,
+ {NCR_860_ID, 0x00, "ncr 53c860 fast20 scsi", 4, 8, 5,
+ FE_ULTRA|FE_CLK80|FE_CACHE_SET|FE_LDSTR|FE_PFEN}
+ ,
+ {NCR_875_ID, 0x00, "ncr 53c875 fast20 wide scsi", 7, 16, 5,
+ FE_WIDE|FE_ULTRA|FE_CLK80|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
+ ,
+ {NCR_875_ID, 0x02, "ncr 53c875 fast20 wide scsi", 7, 16, 5,
+ FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
+ ,
+ {NCR_875_ID2, 0x00, "ncr 53c875j fast20 wide scsi", 7, 16, 5,
+ FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
+ ,
+ {NCR_885_ID, 0x00, "ncr 53c885 fast20 wide scsi", 7, 16, 5,
+ FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
+ ,
+ {NCR_895_ID, 0x00, "ncr 53c895 fast40 wide scsi", 7, 31, 7,
+ FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
+ ,
+ {NCR_896_ID, 0x00, "ncr 53c896 fast40 wide scsi", 7, 31, 7,
+ FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
+};
+
+static int ncr_chip_lookup(u_long device_id, u_char revision_id)
+{
+ int i, found;
+
+ found = -1;
+ for (i = 0; i < sizeof(ncr_chip_table)/sizeof(ncr_chip_table[0]); i++) {
+ if (device_id == ncr_chip_table[i].device_id &&
+ ncr_chip_table[i].minrevid <= revision_id) {
+ if (found < 0 ||
+ ncr_chip_table[found].minrevid
+ < ncr_chip_table[i].minrevid) {
+ found = i;
+ }
+ }
+ }
+ return found;
+}
+
+/*----------------------------------------------------------
+**
** Probe the hostadapter.
**
**----------------------------------------------------------
*/
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
int
ncr_probe(parent, match, aux)
@@ -3325,54 +3531,89 @@ ncr_probe(parent, match, aux)
void *aux;
{
struct pci_attach_args *pa = aux;
+ u_char rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0xff;
#if 0
struct cfdata *cf = match;
if (!pci_targmatch(cf, pa))
return 0;
#endif
- if (pa->pa_id != NCR_810_ID &&
- pa->pa_id != NCR_815_ID &&
- pa->pa_id != NCR_825_ID &&
- pa->pa_id != NCR_860_ID &&
- pa->pa_id != NCR_875_ID)
+ if (ncr_chip_lookup(pa->pa_id, rev) < 0)
return 0;
return 1;
}
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#else /* !__OpenBSD__ */
static char* ncr_probe (pcici_t tag, pcidi_t type)
{
u_char rev = pci_conf_read (tag, PCI_CLASS_REG) & 0xff;
- switch (type) {
+ int i;
- case NCR_810_ID:
- return (rev & 0xf0) == 0x00
- ? ("ncr 53c810 scsi")
- : ("ncr 53c810a scsi");
+ i = ncr_chip_lookup(type, rev);
+ if (i >= 0)
+ return ncr_chip_table[i].name;
- case NCR_815_ID:
- return ("ncr 53c815 scsi");
+ return (NULL);
+}
- case NCR_825_ID:
- return (rev & 0xf0) == 0x00
- ? ("ncr 53c825 wide scsi")
- : ("ncr 53c825a wide scsi");
+#endif /* !__OpenBSD__ */
- case NCR_860_ID:
- return ("ncr 53c860 scsi");
- case NCR_875_ID:
- return ("ncr 53c875 wide scsi");
- }
- return (NULL);
-}
+/*==========================================================
+**
+** NCR chip clock divisor table.
+** Divisors are multiplied by 10,000,000 in order to make
+** calculations more simple.
+**
+**==========================================================
+*/
-#endif /* !(__NetBSD__ || __OpenBSD__) */
+#define _5M 5000000
+static u_long div_10M[] =
+ {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M};
+/*===============================================================
+**
+** NCR chips allow burst lengths of 2, 4, 8, 16, 32, 64, 128
+** transfers. 32,64,128 are only supported by 875 and 895 chips.
+** We use log base 2 (burst length) as internal code, with
+** value 0 meaning "burst disabled".
+**
+**===============================================================
+*/
+
+/*
+ * Burst length from burst code.
+ */
+#define burst_length(bc) (!(bc))? 0 : 1 << (bc)
+
+/*
+ * Burst code from io register bits.
+ */
+#define burst_code(dmode, ctest4, ctest5) \
+ (ctest4) & 0x80? 0 : (((dmode) & 0xc0) >> 6) + ((ctest5) & 0x04) + 1
+
+/*
+ * Set initial io register bits from burst code.
+ */
+static void ncr_init_burst(ncb_p np, u_char bc)
+{
+ np->rv_ctest4 &= ~0x80;
+ np->rv_dmode &= ~(0x3 << 6);
+ np->rv_ctest5 &= ~0x4;
+
+ if (!bc) {
+ np->rv_ctest4 |= 0x80;
+ }
+ else {
+ --bc;
+ np->rv_dmode |= ((bc & 0x3) << 6);
+ np->rv_ctest5 |= (bc & 0x4);
+ }
+}
/*==========================================================
**
@@ -3383,10 +3624,7 @@ static char* ncr_probe (pcici_t tag, pcidi_t type)
**==========================================================
*/
-#define MIN_ASYNC_PD 40
-#define MIN_SYNC_PD 20
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
void
ncr_attach(parent, self, aux)
struct device *parent, *self;
@@ -3400,33 +3638,15 @@ ncr_attach(parent, self, aux)
pci_intr_handle_t intrhandle;
const char *intrstr;
ncb_p np = (void *)self;
- int wide = 0;
+ u_long period;
+ int i;
u_char rev = pci_conf_read(pc, pa->pa_tag, PCI_CLASS_REG) & 0xff;
- printf(": NCR ");
- switch (pa->pa_id) {
- case NCR_810_ID:
- printf((rev & 0xf0) == 0x00 ? "53c810" : "53c810a");
- break;
- case NCR_815_ID:
- printf("53c815");
- break;
- case NCR_825_ID:
- printf((rev & 0xf0) == 0x00 ? "53c825 Wide" : "53c825a Wide");
- wide = 1;
- break;
- case NCR_860_ID:
- printf("53c860");
- break;
- case NCR_875_ID:
- printf("53c875 Wide");
- wide = 1;
- break;
- }
- printf(" SCSI\n");
-
- np->sc_memt = memt;
+ np->sc_st = memt;
np->sc_pc = pc;
+ np->ccb = (ccb_p) malloc (sizeof (struct ccb), M_DEVBUF, M_WAITOK);
+ if (!np->ccb) return;
+ bzero (np->ccb, sizeof (*np->ccb));
/*
** Try to map the controller chip to
@@ -3436,15 +3656,14 @@ ncr_attach(parent, self, aux)
retval = pci_mem_find(pc, pa->pa_tag, 0x14, &np->paddr,
&memsize, &cacheable);
if (retval) {
- printf("%s: couldn't find memory region\n", self->dv_xname);
+ printf("\n%s: couldn't find memory region\n", self->dv_xname);
return;
}
/* Map the memory. Note that we never want it to be cacheable. */
- retval = bus_space_map(pa->pa_memt, np->paddr, memsize, 0,
- &np->sc_bah);
+ retval = bus_space_map(pa->pa_memt, np->paddr, memsize, 0, &np->sc_sh);
if (retval) {
- printf("%s: couldn't map memory region\n", self->dv_xname);
+ printf("\n%s: couldn't map memory region\n", self->dv_xname);
return;
}
@@ -3454,28 +3673,27 @@ ncr_attach(parent, self, aux)
retval = pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin,
pa->pa_intrline, &intrhandle);
if (retval) {
- printf("%s: couldn't map interrupt\n", self->dv_xname);
+ printf("\n%s: couldn't map interrupt\n", self->dv_xname);
return;
}
intrstr = pci_intr_string(pc, intrhandle);
-#ifndef __OpenBSD__
- np->sc_ih = pci_intr_establish(pc, intrhandle, IPL_BIO,
- ncr_intr, np);
-#else /* !__OpenBSD__ */
np->sc_ih = pci_intr_establish(pc, intrhandle, IPL_BIO,
ncr_intr, np, self->dv_xname);
-#endif /* __OpenBSD__ */
if (np->sc_ih == NULL) {
- printf("%s: couldn't establish interrupt", self->dv_xname);
+ printf("\n%s: couldn't establish interrupt", self->dv_xname);
if (intrstr != NULL)
printf(" at %s", intrstr);
printf("\n");
return;
}
+
+ i = ncr_chip_lookup(pa->pa_id, rev);
if (intrstr != NULL)
- printf("%s: interrupting at %s\n", self->dv_xname, intrstr);
+ printf(": %s, %s\n", ncr_chip_table[i].name, intrstr);
+ else
+ printf(": %s\n", ncr_chip_table[i].name);
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#else /* !__OpenBSD__ */
static void ncr_attach (pcici_t config_id, int unit)
{
@@ -3487,9 +3705,12 @@ static void ncr_attach (pcici_t config_id, int unit)
#if (__FreeBSD__ >= 2)
struct scsibus_data *scbus;
#endif
+ u_char rev = 0;
+ u_long period;
+ int i;
/*
- ** allocate structure
+ ** allocate and initialize structures.
*/
if (!np) {
@@ -3497,12 +3718,12 @@ static void ncr_attach (pcici_t config_id, int unit)
if (!np) return;
ncrp[unit]=np;
}
+ bzero (np, sizeof (*np));
- /*
- ** initialize structure.
- */
+ np->ccb = (ccb_p) malloc (sizeof (struct ccb), M_DEVBUF, M_WAITOK);
+ if (!np->ccb) return;
+ bzero (np->ccb, sizeof (*np->ccb));
- bzero (np, sizeof (*np));
np->unit = unit;
/*
@@ -3530,81 +3751,304 @@ static void ncr_attach (pcici_t config_id, int unit)
return;
#endif
-#endif /* !(__NetBSD__ || __OpenBSD__) */
+#endif /* !__OpenBSD__ */
/*
** Save some controller register default values
*/
- np->rv_dmode = INB (nc_dmode);
- np->rv_dcntl = INB (nc_dcntl) | CLSE | PFEN | NOCOM;
- np->rv_ctest3 = INB (nc_ctest3);
- np->rv_ctest5 = 0;
- np->rv_scntl3 = 0x13; /* default: 40MHz clock */
+ np->rv_scntl3 = INB(nc_scntl3) & 0x77;
+ np->rv_dmode = INB(nc_dmode) & 0xce;
+ np->rv_dcntl = INB(nc_dcntl) & 0xa9;
+ np->rv_ctest3 = INB(nc_ctest3) & 0x01;
+ np->rv_ctest4 = INB(nc_ctest4) & 0x88;
+ np->rv_ctest5 = INB(nc_ctest5) & 0x24;
+ np->rv_gpcntl = INB(nc_gpcntl);
+ np->rv_stest2 = INB(nc_stest2) & 0x20;
+
+ if (bootverbose >= 2) {
+ printf ("\tBIOS values: SCNTL3:%02x DMODE:%02x DCNTL:%02x\n",
+ np->rv_scntl3, np->rv_dmode, np->rv_dcntl);
+ printf ("\t CTEST3:%02x CTEST4:%02x CTEST5:%02x\n",
+ np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
+ }
+
+ np->rv_dcntl |= NOCOM;
/*
** Do chip dependent initialization.
*/
- np->maxwide = 0;
- np->ns_sync = 25; /* in units of 4ns */
- np->maxoffs = 8;
+#ifndef __OpenBSD__
+ rev = pci_conf_read (config_id, PCI_CLASS_REG) & 0xff;
+#endif /* !__OpenBSD__ */
+
+ /*
+ ** Get chip features from chips table.
+ */
+#ifndef __OpenBSD__
+ i = ncr_chip_lookup(pci_conf_read(config_id, PCI_ID_REG), rev);
+#endif /* !__OpenBSD__ */
+
+ if (i >= 0) {
+ np->maxburst = ncr_chip_table[i].maxburst;
+ np->maxoffs = ncr_chip_table[i].maxoffs;
+ np->clock_divn = ncr_chip_table[i].clock_divn;
+ np->features = ncr_chip_table[i].features;
+ } else { /* Should'nt happen if probe() is ok */
+ np->maxburst = 4;
+ np->maxoffs = 8;
+ np->clock_divn = 4;
+ np->features = FE_ERL;
+ }
+
+ np->maxwide = np->features & FE_WIDE ? 1 : 0;
+ np->clock_khz = np->features & FE_CLK80 ? 80000 : 40000;
+ if (np->features & FE_QUAD) np->multiplier = 4;
+ else if (np->features & FE_DBLR) np->multiplier = 2;
+ else np->multiplier = 1;
/*
** Get the frequency of the chip's clock.
** Find the right value for scntl3.
*/
+ if (np->features & (FE_ULTRA|FE_ULTRA2))
+ ncr_getclock(np, np->multiplier);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- switch (pa->pa_id) {
-#else /* !(__NetBSD__ || __OpenBSD__) */
- switch (pci_conf_read (config_id, PCI_ID_REG)) {
-#endif /* __NetBSD__ || __OpenBSD__ */
- case NCR_825_ID:
- {
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
- u_char rev = pci_conf_read (config_id, PCI_CLASS_REG) & 0xff;
-#endif /* !(__NetBSD__ || __OpenBSD__) */
- if ((rev & 0xf0) == 0x10)
- np->maxoffs = 16;
- np->maxwide = 1;
- break;
- }
- case NCR_860_ID:
- np->rv_scntl3 = 0x35; /* always assume 80MHz clock for 860 */
- /*np->ns_sync = 12;*/ /* in units of 4ns */
- break;
- case NCR_875_ID:
- np->maxwide = 1;
- /*np->ns_sync = 12;*/ /* in units of 4ns */
- np->maxoffs = 16;
#ifdef NCR_TEKRAM_EEPROM
- if (bootverbose)
+ if (bootverbose) {
+ printf ("%s: Tekram EEPROM read %s\n",
+ ncr_name(np),
+ read_tekram_eeprom (np, NULL) ?
+ "succeeded" : "failed");
+ }
+#endif /* NCR_TEKRAM_EEPROM */
+
+ /*
+ * If scntl3 != 0, we assume BIOS is present.
+ */
+ if (np->rv_scntl3)
+ np->features |= FE_BIOS;
+
+ /*
+ * Divisor to be used for async (timer pre-scaler).
+ */
+ i = np->clock_divn - 1;
+ while (i >= 0) {
+ --i;
+ if (10ul * SCSI_NCR_MIN_ASYNC * np->clock_khz > div_10M[i]) {
+ ++i;
+ break;
+ }
+ }
+ np->rv_scntl3 = i+1;
+
+ /*
+ * Minimum synchronous period factor supported by the chip.
+ * Btw, 'period' is in tenths of nanoseconds.
+ */
+
+ period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;
+ if (period <= 250) np->minsync = 10;
+ else if (period <= 303) np->minsync = 11;
+ else if (period <= 500) np->minsync = 12;
+ else np->minsync = (period + 40 - 1) / 40;
+
+ /*
+ * Check against chip SCSI standard support (SCSI-2,ULTRA,ULTRA2).
+ */
+
+ if (np->minsync < 25 && !(np->features & (FE_ULTRA|FE_ULTRA2)))
+ np->minsync = 25;
+ else if (np->minsync < 12 && !(np->features & FE_ULTRA2))
+ np->minsync = 12;
+
+ /*
+ * Maximum synchronous period factor supported by the chip.
+ */
+
+ period = (11 * div_10M[np->clock_divn - 1]) / (4 * np->clock_khz);
+ np->maxsync = period > 2540 ? 254 : period / 10;
+
+ /*
+ * Now, some features available with Symbios compatible boards.
+ * LED support through GPIO0 and DIFF support.
+ */
+
+#ifdef SCSI_NCR_SYMBIOS_COMPAT
+ if (!(np->rv_gpcntl & 0x01))
+ np->features |= FE_LED0;
+#if 0 /* Not safe enough without NVRAM support or user settable option */
+ if (!(INB(nc_gpreg) & 0x08))
+ np->features |= FE_DIFF;
+#endif
+#endif /* SCSI_NCR_SYMBIOS_COMPAT */
+
+ /*
+ * Prepare initial IO registers settings.
+ * Trust BIOS only if we believe we have one and if we want to.
+ */
+#ifdef SCSI_NCR_TRUST_BIOS
+ if (!(np->features & FE_BIOS)) {
+#else
+ if (1) {
+#endif
+ np->rv_dmode = 0;
+ np->rv_dcntl = NOCOM;
+ np->rv_ctest3 = 0;
+ np->rv_ctest4 = MPEE;
+ np->rv_ctest5 = 0;
+ np->rv_stest2 = 0;
+
+ if (np->features & FE_ERL)
+ np->rv_dmode |= ERL; /* Enable Read Line */
+ if (np->features & FE_BOF)
+ np->rv_dmode |= BOF; /* Burst Opcode Fetch */
+ if (np->features & FE_ERMP)
+ np->rv_dmode |= ERMP; /* Enable Read Multiple */
+ if (np->features & FE_CLSE)
+ np->rv_dcntl |= CLSE; /* Cache Line Size Enable */
+ if (np->features & FE_WRIE)
+ np->rv_ctest3 |= WRIE; /* Write and Invalidate */
+ if (np->features & FE_PFEN)
+ np->rv_dcntl |= PFEN; /* Prefetch Enable */
+ if (np->features & FE_DFS)
+ np->rv_ctest5 |= DFS; /* Dma Fifo Size */
+ if (np->features & FE_DIFF)
+ np->rv_stest2 |= 0x20; /* Differential mode */
+ ncr_init_burst(np, np->maxburst); /* Max dwords burst length */
+ } else {
+ np->maxburst =
+ burst_code(np->rv_dmode, np->rv_ctest4, np->rv_ctest5);
+ }
+
+#ifndef NCR_IOMAPPED
+ /*
+ ** Get on-chip SRAM address, if supported
+ */
+#ifndef __OpenBSD__
+ if ((np->features & FE_RAM) && sizeof(struct script) <= 4096)
+ (void)(!pci_map_mem (config_id,0x18, &np->vaddr2, &np->paddr2));
+#endif /* __OpenBSD__ */
+#endif /* !NCR_IOMAPPED */
+
+ /*
+ ** Allocate structure for script relocation.
+ */
+#ifdef __FreeBSD__
+ if (np->vaddr2 != NULL) {
+ np->script = (struct script *) np->vaddr2;
+ np->p_script = np->paddr2;
+ } else if (sizeof (struct script) > PAGE_SIZE) {
+ np->script = (struct script*) vm_page_alloc_contig
+ (round_page(sizeof (struct script)),
+ 0x100000, 0xffffffff, PAGE_SIZE);
+#else
+ if (ISSCRIPTRAMMAPPED(np)) {
+ /*
+ * A NULL value means that the script is in the chip's
+ * on-board RAM and has no virtual address.
+ */
+ np->script = NULL;
+ np->p_script = np->paddr2;
+#endif /* __FreeBSD__ */
+ } else {
+ np->script = (struct script *)
+ malloc (sizeof (struct script), M_DEVBUF, M_WAITOK);
+ }
+
+#ifdef __FreeBSD__
+ if (sizeof (struct scripth) > PAGE_SIZE) {
+ np->scripth = (struct scripth*) vm_page_alloc_contig
+ (round_page(sizeof (struct scripth)),
+ 0x100000, 0xffffffff, PAGE_SIZE);
+ } else
+#endif /* __FreeBSD__ */
{
- printf ("%s: Tekram EEPROM read %s\n",
- ncr_name(np),
- read_tekram_eeprom (np, NULL) ?
- "succeeded" : "failed");
+ np->scripth = (struct scripth *)
+ malloc (sizeof (struct scripth), M_DEVBUF, M_WAITOK);
+ }
+
+#ifdef SCSI_NCR_PCI_CONFIG_FIXUP
+ /*
+ ** If cache line size is enabled, check PCI config space and
+ ** try to fix it up if necessary.
+ */
+#ifdef PCIR_CACHELNSZ /* To be sure that new PCI stuff is present */
+ {
+ u_char cachelnsz = pci_cfgread(config_id, PCIR_CACHELNSZ, 1);
+ u_short command = pci_cfgread(config_id, PCIR_COMMAND, 2);
+
+ if (!cachelnsz) {
+ cachelnsz = 8;
+ printf("%s: setting PCI cache line size register to %d.\n",
+ ncr_name(np), (int)cachelnsz);
+ pci_cfgwrite(config_id, PCIR_CACHELNSZ, cachelnsz, 1);
+ }
+
+ if (!(command & (1<<4))) {
+ command |= (1<<4);
+ printf("%s: setting PCI command write and invalidate.\n",
+ ncr_name(np));
+ pci_cfgwrite(config_id, PCIR_COMMAND, command, 2);
}
-#endif /* NCR_TEKRAM_EEPROM */
- ncr_getclock(np);
- break;
}
+#endif /* PCIR_CACHELNSZ */
+
+#endif /* SCSI_NCR_PCI_CONFIG_FIXUP */
/*
- ** Patch script to physical addresses
+ ** Bells and whistles ;-)
*/
+ if (bootverbose)
+ printf("%s: minsync=%d, maxsync=%d, maxoffs=%d, %d dwords burst, %s dma fifo\n",
+ ncr_name(np), np->minsync, np->maxsync, np->maxoffs,
+ burst_length(np->maxburst),
+ (np->rv_ctest5 & DFS) ? "large" : "normal");
+
+ /*
+ ** Print some complementary information that can be helpfull.
+ */
+ if (bootverbose)
+ printf("%s: %s, %s IRQ driver%s\n",
+ ncr_name(np),
+ np->rv_stest2 & 0x20 ? "differential" : "single-ended",
+ np->rv_dcntl & IRQM ? "totem pole" : "open drain",
+ ISSCRIPTRAMMAPPED(np) ? ", using on-chip SRAM" : "");
+
+ /*
+ ** Patch scripts to physical addresses
+ */
+ ncr_script_fill (&script0, &scripth0);
+
+ if (np->script)
+ np->p_script = vtophys(np->script);
+ np->p_scripth = vtophys(np->scripth);
- ncr_script_fill (&script0);
- ncr_script_copy_and_bind (&script0, np);
- np->ccb.p_ccb = vtophys (&np->ccb);
+ ncr_script_copy_and_bind (np, (ncrcmd *) &script0,
+ (ncrcmd *) np->script, sizeof(struct script));
+
+ ncr_script_copy_and_bind (np, (ncrcmd *) &scripth0,
+ (ncrcmd *) np->scripth, sizeof(struct scripth));
+
+ np->ccb->p_ccb = vtophys (np->ccb);
+
+ /*
+ ** Patch the script for LED support.
+ */
+
+ if (np->features & FE_LED0) {
+ WRITESCRIPT(reselect[0], SCR_REG_REG(gpreg, SCR_OR, 0x01));
+ WRITESCRIPT(reselect1[0], SCR_REG_REG(gpreg, SCR_AND, 0xfe));
+ WRITESCRIPT(reselect2[0], SCR_REG_REG(gpreg, SCR_AND, 0xfe));
+ }
/*
** init data structure
*/
np->jump_tcb.l_cmd = SCR_BO(SCR_JUMP);
- np->jump_tcb.l_paddr = SCR_BO(NCB_SCRIPT_PHYS (np, abort));
+ np->jump_tcb.l_paddr = SCR_BO(NCB_SCRIPTH_PHYS (np, abort));
/*
** Get SCSI addr of host adapter (set by bios?).
@@ -3619,12 +4063,12 @@ static void ncr_attach (pcici_t config_id, int unit)
*/
{
int reg;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
u_long config_id = pa->pa_tag;
-#endif /* __NetBSD__ || __OpenBSD__ */
+#endif /* __OpenBSD__ */
for (reg=0; reg<256; reg+=4) {
if (reg%16==0) printf ("reg[%2x]", reg);
- printf (" %08x", (int)pci_conf_read (pc, config_id, reg));
+ printf (" %08x", (int)pci_conf_read (config_id, reg));
if (reg%16==12) printf ("\n");
}
}
@@ -3648,14 +4092,14 @@ static void ncr_attach (pcici_t config_id, int unit)
return;
};
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+#ifndef __OpenBSD__
/*
** Install the interrupt handler.
*/
if (!pci_map_int (config_id, ncr_intr, np, &bio_imask))
printf ("\tinterruptless mode: reduced performance.\n");
-#endif /* __NetBSD__ || __OpenBSD__ */
+#endif /* !__OpenBSD__ */
/*
** After SCSI devices have been opened, we cannot
@@ -3679,30 +4123,25 @@ static void ncr_attach (pcici_t config_id, int unit)
** look for the SCSI devices on the bus ..
*/
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
np->sc_link.adapter_softc = np;
np->sc_link.adapter_target = np->myaddr;
np->sc_link.openings = 1;
-#ifndef __OpenBSD__
- np->sc_link.channel = SCSI_CHANNEL_ONLY_ONE;
- np->sc_link.max_target = wide ? 15 : 7;
-#else
if (np->maxwide)
np->sc_link.adapter_buswidth = MAX_TARGET;
-#endif /* __OpenBSD__ */
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#else /* !__OpenBSD__ */
np->sc_link.adapter_unit = unit;
np->sc_link.adapter_softc = np;
np->sc_link.adapter_targ = np->myaddr;
np->sc_link.fordriver = 0;
-#endif /* !(__NetBSD__ || __OpenBSD__) */
+#endif /* !__OpenBSD__ */
np->sc_link.adapter = &ncr_switch;
np->sc_link.device = &ncr_dev;
np->sc_link.flags = 0;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
config_found(self, &np->sc_link, scsiprint);
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#else /* !__OpenBSD__ */
#if (__FreeBSD__ >= 2)
scbus = scsi_alloc_bus();
if(!scbus)
@@ -3733,7 +4172,7 @@ static void ncr_attach (pcici_t config_id, int unit)
#else
scsi_attachdevs (&np->sc_link);
#endif /* !__FreeBSD__ >= 2 */
-#endif /* !(__NetBSD__ || __OpenBSD__) */
+#endif /* !__OpenBSD__ */
/*
** start the timeout daemon
@@ -3746,6 +4185,7 @@ static void ncr_attach (pcici_t config_id, int unit)
*/
np->order = M_SIMPLE_TAG;
+
/*
** Done.
*/
@@ -3762,15 +4202,15 @@ static void ncr_attach (pcici_t config_id, int unit)
**==========================================================
*/
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
static int
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#else /* !__OpenBSD__ */
static void
-#endif /* __NetBSD__ || __OpenBSD__ */
+#endif /* __OpenBSD__ */
ncr_intr(vnp)
void *vnp;
{
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
int n = 0;
#endif
ncb_p np = vnp;
@@ -3786,8 +4226,8 @@ ncr_intr(vnp)
ncr_exception (np);
} while (INB(nc_istat) & (INTF|SIP|DIP));
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- n = 1;
+#ifdef __OpenBSD__
+ n=1;
#endif
np->ticks = 100;
};
@@ -3795,7 +4235,7 @@ ncr_intr(vnp)
if (DEBUG_FLAGS & DEBUG_TINY) printf ("]\n");
splx (oldspl);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
return (n);
#endif
}
@@ -3810,11 +4250,11 @@ ncr_intr(vnp)
**==========================================================
*/
-static INT32 ncr_start (struct scsi_xfer * xp)
+static int32_t ncr_start (struct scsi_xfer * xp)
{
- ncb_p np = (ncb_p) xp->sc_link->adapter_softc;
+ ncb_p np = (ncb_p) xp->sc_link->adapter_softc;
- struct scsi_generic * cmd = xp->cmd;
+ struct scsi_generic * cmd = (struct scsi_generic *)xp->cmd;
ccb_p cp;
lcb_p lp;
tcb_p tp = &np->target[xp->sc_link->target];
@@ -3875,21 +4315,21 @@ static INT32 ncr_start (struct scsi_xfer * xp)
if ((unsigned)xp->datalen > 128*1024*1024) {
PRINT_ADDR(xp);
- printf ("trying to transfer %8x bytes, mem addr = %p\n",
+ printf ("trying to transfer %8x bytes, mem addr = %p\n",
xp->datalen, xp->data);
{
- int i;
+ int j;
PRINT_ADDR(xp);
printf ("command: %2x (", cmd->opcode);
- for (i = 0; i<11; i++)
- printf (" %2x", cmd->bytes[i]);
+ for (j = 0; j<11; j++)
+ printf (" %2x", cmd->bytes[j]);
printf (")\n");
}
}
if (DEBUG_FLAGS & DEBUG_TINY) {
PRINT_ADDR(xp);
- printf ("CMD=%x F=%x A=%p L=%x ",
+ printf ("CMD=%x F=%x A=%p L=%x ",
cmd->opcode, (unsigned)xp->flags, xp->data,
(unsigned)xp->datalen);
}
@@ -3925,7 +4365,8 @@ static INT32 ncr_start (struct scsi_xfer * xp)
oldspl = splbio();
- if (!(cp=ncr_get_ccb (np, flags, xp->sc_link->target, xp->sc_link->lun))) {
+ if (!(cp=ncr_get_ccb (np, flags, xp->sc_link->target,
+ xp->sc_link->lun))) {
printf ("%s: no ccb.\n", ncr_name (np));
xp->error = XS_DRIVER_STUFFUP;
splx(oldspl);
@@ -3941,7 +4382,11 @@ static INT32 ncr_start (struct scsi_xfer * xp)
*/
bzero (&cp->phys.header.stamp, sizeof (struct tstamp));
+#ifdef __OpenBSD__
cp->phys.header.stamp.start = mono_time;
+#else
+ gettime(&cp->phys.header.stamp.start);
+#endif
/*----------------------------------------------------
**
@@ -3955,15 +4400,26 @@ static INT32 ncr_start (struct scsi_xfer * xp)
*/
if (tp->quirks & QUIRK_UPDATE) {
-#ifdef NEW_SCSICONF
- tp->quirks = xp->sc_link->quirks;
-#else
+#ifdef __OpenBSD__
tp->quirks = ncr_lookup ((char*) &tp->inqdata[0]);
+#else
+ int q = xp->sc_link->quirks;
+ tp->quirks = QUIRK_NOMSG;
+ if (q & SD_Q_NO_TAGS)
+ tp->quirks |= QUIRK_NOTAGS;
+ if (q & SD_Q_NO_SYNC)
+ tp->quirks |= QUIRK_NOSYNC;
+ if (q & SD_Q_NO_WIDE)
+ tp->quirks |= QUIRK_NOWIDE16;
#endif
- if (tp->quirks & ~QUIRK_NOMSG) {
+ if (bootverbose && (tp->quirks & ~QUIRK_NOMSG)) {
PRINT_ADDR(xp);
- printf ("quirks=%x.\n", tp->quirks);
+ printf ("NCR quirks=0x%x\n", tp->quirks);
};
+ /*
+ ** set number of tags
+ */
+ ncr_setmaxtags (tp, tp->usrtags);
};
/*---------------------------------------------------
@@ -3975,7 +4431,7 @@ static INT32 ncr_start (struct scsi_xfer * xp)
nego = 0;
- if (tp->inqdata[7]) {
+ if (!tp->nego_cp && tp->inqdata[7]) {
/*
** negotiate wide transfers ?
*/
@@ -3992,7 +4448,7 @@ static INT32 ncr_start (struct scsi_xfer * xp)
*/
if (!nego && !tp->period) {
- if (SCSI_NCR_MAX_SYNC
+ if (SCSI_NCR_DFLT_SYNC
#ifdef NCR_CDROM_ASYNC
&& ((tp->inqdata[0] & 0x1f) != 5)
#endif /* NCR_CDROM_ASYNC */
@@ -4005,6 +4461,15 @@ static INT32 ncr_start (struct scsi_xfer * xp)
printf ("asynchronous.\n");
};
};
+
+ /*
+ ** remember nego is pending for the target.
+ ** Avoid to start a nego for all queued commands
+ ** when tagged command queuing is enabled.
+ */
+
+ if (nego)
+ tp->nego_cp = cp;
};
/*---------------------------------------------------
@@ -4042,7 +4507,7 @@ static INT32 ncr_start (struct scsi_xfer * xp)
*/
idmsg = M_IDENTIFY | xp->sc_link->lun;
- if ((cp!=&np->ccb) && (np->disc))
+ if ((cp!=np->ccb) && (np->disc))
idmsg |= 0x40;
msgptr = cp->scsi_smsg;
@@ -4228,7 +4693,11 @@ static INT32 ncr_start (struct scsi_xfer * xp)
*/
cp->jump_ccb.l_cmd = SCR_BO((SCR_JUMP ^ IFFALSE (DATA (cp->tag))));
+#ifdef __OpenBSD__
cp->tlimit = mono_time.tv_sec + xp->timeout / 1000 + 2;
+#else
+ cp->tlimit = time.tv_sec + xp->timeout / 1000 + 2;
+#endif
cp->magic = CCB_MAGIC;
/*
@@ -4244,8 +4713,8 @@ static INT32 ncr_start (struct scsi_xfer * xp)
if(DEBUG_FLAGS & DEBUG_QUEUE)
printf ("%s: queuepos=%d tryoffset=%d.\n", ncr_name (np),
np->squeueput,
- SCR_BO((unsigned)(np->script->startpos[0]))-
- (NCB_SCRIPT_PHYS (np, tryloop)));
+ (unsigned)(READSCRIPT(startpos[0])-
+ (NCB_SCRIPTH_PHYS (np, tryloop))));
/*
** Script processor may be waiting for reselect.
@@ -4263,11 +4732,11 @@ static INT32 ncr_start (struct scsi_xfer * xp)
** Command is successfully queued.
*/
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- if (!(flags & SCSI_POLL)) {
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#ifdef __OpenBSD__
+ if (!(flags & SCSI_POLL)) {
+#else /* !__OpenBSD__ */
if (!(flags & SCSI_NOMASK)) {
-#endif /* __NetBSD__ || __OpenBSD__ */
+#endif /* __OpenBSD__ */
if (np->lasttime) {
if(DEBUG_FLAGS & DEBUG_TINY) printf ("Q");
return(SUCCESSFULLY_QUEUED);
@@ -4316,11 +4785,11 @@ static INT32 ncr_start (struct scsi_xfer * xp)
printf ("%s: result: %x %x.\n",
ncr_name (np), cp->host_status, cp->scsi_status);
};
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- if (!(flags & SCSI_POLL))
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#ifdef __OpenBSD__
+ if (!(flags & SCSI_POLL))
+#else /* !__OpenBSD__ */
if (!(flags & SCSI_NOMASK))
-#endif /* __NetBSD__ || __OpenBSD__ */
+#endif /* __OpenBSD__ */
return (SUCCESSFULLY_QUEUED);
switch (xp->error) {
case 0 : return (COMPLETE);
@@ -4369,7 +4838,7 @@ void ncr_complete (ncb_p np, ccb_p cp)
ncb_profile (np, cp);
if (DEBUG_FLAGS & DEBUG_TINY)
- printf ("CCB=%lx STAT=%x/%x\n", (unsigned long)cp,
+ printf ("CCB=%lx STAT=%x/%x\n", (unsigned long)cp & 0xfff,
cp->host_status,cp->scsi_status);
xp = cp->xfer;
@@ -4378,6 +4847,15 @@ void ncr_complete (ncb_p np, ccb_p cp)
lp = tp->lp[xp->sc_link->lun];
/*
+ ** We donnot queue more than 1 ccb per target
+ ** with negotiation at any time. If this ccb was
+ ** used for negotiation, clear this info in the tcb.
+ */
+
+ if (cp == tp->nego_cp)
+ tp->nego_cp = 0;
+
+ /*
** Check for parity errors.
*/
@@ -4387,7 +4865,7 @@ void ncr_complete (ncb_p np, ccb_p cp)
/*
** fallback to asynch transfer.
*/
- tp->usrsync = 255;
+ tp->usrsync=255;
tp->period = 0;
};
@@ -4408,21 +4886,21 @@ void ncr_complete (ncb_p np, ccb_p cp)
printf ("extended error %d.\n", cp->xerr_status);
break;
};
- if (cp->host_status == HS_COMPLETE)
+ if (cp->host_status==HS_COMPLETE)
cp->host_status = HS_FAIL;
};
/*
** Check the status.
*/
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- if (xp->error != XS_NOERROR) {
-
- /*
+#ifdef __OpenBSD__
+ if (xp->error != XS_NOERROR) {
+
+ /*
** Don't override the error value.
*/
- } else
-#endif /* __NetBSD__ || __OpenBSD__ */
+ } else
+#endif /* __OpenBSD__ */
if ( (cp->host_status == HS_COMPLETE)
&& (cp->scsi_status == S_GOOD)) {
@@ -4454,12 +4932,6 @@ void ncr_complete (ncb_p np, ccb_p cp)
bcopy ( xp->data,
&tp->inqdata,
sizeof (tp->inqdata));
-
- /*
- ** set number of tags
- */
- ncr_setmaxtags (tp, tp->usrtags);
-
/*
** prepare negotiation of synch and wide.
*/
@@ -4475,21 +4947,20 @@ void ncr_complete (ncb_p np, ccb_p cp)
** Announce changes to the generic driver
*/
if (lp) {
- ncr_settags (tp, lp);
if (lp->reqlink != lp->actlink)
ncr_opennings (np, lp, xp);
};
tp->bytes += xp->datalen;
tp->transfers ++;
-#if !(defined(__NetBSD__) || defined(__OpenBSD__))
+#ifndef __OpenBSD__
} else if (xp->flags & SCSI_ERR_OK) {
/*
** Not correct, but errors expected.
*/
xp->resid = 0;
-#endif /* !(__NetBSD__ || __OpenBSD__) */
+#endif /* !__OpenBSD__ */
} else if ((cp->host_status == HS_COMPLETE)
&& (cp->scsi_status == (S_SENSE|S_GOOD))) {
@@ -4507,10 +4978,11 @@ void ncr_complete (ncb_p np, ccb_p cp)
};
} else if ((cp->host_status == HS_COMPLETE)
- && (cp->scsi_status == S_BUSY)) {
+ && ((cp->scsi_status == S_BUSY)
+ || (cp->scsi_status == S_CONFLICT))) {
/*
- ** Target is busy.
+ ** Target is busy, or reservation conflict
*/
xp->error = XS_BUSY;
@@ -4520,6 +4992,7 @@ void ncr_complete (ncb_p np, ccb_p cp)
** Device failed selection
*/
xp->error = XS_SELTIMEOUT;
+
} else if(cp->host_status == HS_TIMEOUT) {
/*
@@ -4603,7 +5076,7 @@ void ncr_wakeup (ncb_p np, u_long code)
** complete all jobs that are not IDLE.
*/
- ccb_p cp = &np->ccb;
+ ccb_p cp = np->ccb;
while (cp) {
switch (cp->host_status) {
@@ -4643,7 +5116,6 @@ void ncr_init (ncb_p np, char * msg, u_long code)
int i;
u_long usrsync;
u_char usrwide;
- u_char burstlen;
/*
** Reset chip.
@@ -4651,6 +5123,7 @@ void ncr_init (ncb_p np, char * msg, u_long code)
OUTB (nc_istat, SRST);
DELAY (1000);
+ OUTB (nc_istat, 0);
/*
** Message.
@@ -4670,8 +5143,8 @@ void ncr_init (ncb_p np, char * msg, u_long code)
*/
np->squeueput = 0;
- np->script->startpos[0] = SCR_BO(NCB_SCRIPT_PHYS (np, tryloop));
- np->script->start0 [0] = SCR_BO(SCR_INT ^ IFFALSE (0));
+ WRITESCRIPT(startpos[0], NCB_SCRIPTH_PHYS (np, tryloop));
+ WRITESCRIPT(start0 [0], SCR_INT ^ IFFALSE (0));
/*
** Wakeup all pending jobs.
@@ -4683,13 +5156,10 @@ void ncr_init (ncb_p np, char * msg, u_long code)
** Init chip.
*/
- burstlen = 0xc0; /* XXX 53c875 needs code change to */
- /* be able to use larger bursts */
-
OUTB (nc_istat, 0x00 ); /* Remove Reset, abort ... */
OUTB (nc_scntl0, 0xca ); /* full arb., ena parity, par->ATN */
OUTB (nc_scntl1, 0x00 ); /* odd parity, and remove CRST!! */
- OUTB (nc_scntl3, np->rv_scntl3);/* timing prescaler */
+ ncr_selectclock(np, np->rv_scntl3); /* Select SCSI clock */
OUTB (nc_scid , RRE|np->myaddr);/* host adapter SCSI address */
OUTW (nc_respid, 1ul<<np->myaddr);/* id to respond to */
OUTB (nc_istat , SIGP ); /* Signal Process */
@@ -4697,21 +5167,25 @@ void ncr_init (ncb_p np, char * msg, u_long code)
OUTB (nc_dcntl , np->rv_dcntl);
OUTB (nc_ctest3, np->rv_ctest3);
OUTB (nc_ctest5, np->rv_ctest5);
- OUTB (nc_ctest4, MPEE ); /* enable master parity checking */
- OUTB (nc_stest2, EXT ); /* Extended Sreq/Sack filtering */
+ OUTB (nc_ctest4, np->rv_ctest4);/* enable master parity checking */
+ OUTB (nc_stest2, np->rv_stest2|EXT); /* Extended Sreq/Sack filtering */
OUTB (nc_stest3, TE ); /* TolerANT enable */
OUTB (nc_stime0, 0x0b ); /* HTH = disabled, STO = 0.1 sec. */
-#ifdef __FreeBSD__
- if (bootverbose) {
- printf ("\tBIOS values: dmode: %02x, dcntl: %02x, ctest3: %02x\n",
- np->rv_dmode, np->rv_dcntl, np->rv_ctest3);
- printf ("\tdmode: %02x/%02x, dcntl: %02x/%02x, ctest3: %02x/%02x\n",
- burstlen | ERL | ERMP | BOF, INB (nc_dmode),
- CLSE | PFEN | NOCOM, INB (nc_dcntl),
- WRIE, INB (nc_ctest3));
+ if (bootverbose >= 2) {
+ printf ("\tACTUAL values:SCNTL3:%02x DMODE:%02x DCNTL:%02x\n",
+ np->rv_scntl3, np->rv_dmode, np->rv_dcntl);
+ printf ("\t CTEST3:%02x CTEST4:%02x CTEST5:%02x\n",
+ np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
+ }
+
+ /*
+ ** Enable GPIO0 pin for writing if LED support.
+ */
+
+ if (np->features & FE_LED0) {
+ OUTOFFB (nc_gpcntl, 0x01);
}
-#endif /* __FreeBSD__ */
/*
** Reinitialize usrsync.
@@ -4719,15 +5193,12 @@ void ncr_init (ncb_p np, char * msg, u_long code)
*/
usrsync = 255;
- if (SCSI_NCR_MAX_SYNC) {
- u_long period;
- period =1000000/SCSI_NCR_MAX_SYNC; /* ns = 10e6 / kHz */
- if (period <= 11 * np->ns_sync) {
- if (period < 4 * np->ns_sync)
- usrsync = np->ns_sync;
- else
- usrsync = period / 4;
- };
+ if (SCSI_NCR_DFLT_SYNC) {
+ usrsync = SCSI_NCR_DFLT_SYNC;
+ if (usrsync > np->maxsync)
+ usrsync = np->maxsync;
+ if (usrsync < np->minsync)
+ usrsync = np->minsync;
};
/*
@@ -4802,14 +5273,14 @@ static void ncr_negotiate (struct ncb* np, struct tcb* tp)
** our limit ..
*/
- if (minsync < np->ns_sync)
- minsync = np->ns_sync;
+ if (minsync < np->minsync)
+ minsync = np->minsync;
/*
** divider limit
*/
- if (minsync > (np->ns_sync * 11) / 4)
+ if (minsync > np->maxsync)
minsync = 255;
tp->minsync = minsync;
@@ -4829,15 +5300,86 @@ static void ncr_negotiate (struct ncb* np, struct tcb* tp)
/*==========================================================
**
+** Get clock factor and sync divisor for a given
+** synchronous factor period.
+** Returns the clock factor (in sxfer) and scntl3
+** synchronous divisor field.
+**
+**==========================================================
+*/
+
+static void ncr_getsync(ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p)
+{
+ u_long clk = np->clock_khz; /* SCSI clock frequency in kHz */
+ int div = np->clock_divn; /* Number of divisors supported */
+ u_long fak; /* Sync factor in sxfer */
+ u_long per; /* Period in tenths of ns */
+ u_long kpc; /* (per * clk) */
+
+ /*
+ ** Compute the synchronous period in tenths of nano-seconds
+ */
+ if (sfac <= 10) per = 250;
+ else if (sfac == 11) per = 303;
+ else if (sfac == 12) per = 500;
+ else per = 40 * sfac;
+
+ /*
+ ** Look for the greatest clock divisor that allows an
+ ** input speed faster than the period.
+ */
+ kpc = per * clk;
+ while (--div >= 0)
+ if (kpc >= (div_10M[div] * 4)) break;
+
+ /*
+ ** Calculate the lowest clock factor that allows an output
+ ** speed not faster than the period.
+ */
+ fak = (kpc - 1) / div_10M[div] + 1;
+
+#if 0 /* You can #if 1 if you think this optimization is usefull */
+
+ per = (fak * div_10M[div]) / clk;
+
+ /*
+ ** Why not to try the immediate lower divisor and to choose
+ ** the one that allows the fastest output speed ?
+ ** We dont want input speed too much greater than output speed.
+ */
+ if (div >= 1 && fak < 6) {
+ u_long fak2, per2;
+ fak2 = (kpc - 1) / div_10M[div-1] + 1;
+ per2 = (fak2 * div_10M[div-1]) / clk;
+ if (per2 < per && fak2 <= 6) {
+ fak = fak2;
+ per = per2;
+ --div;
+ }
+ }
+#endif
+
+ if (fak < 4) fak = 4; /* Should never happen, too bad ... */
+
+ /*
+ ** Compute and return sync parameters for the ncr
+ */
+ *fakp = fak - 4;
+ *scntl3p = ((div+1) << 4) + (sfac < 25 ? 0x80 : 0);
+}
+
+/*==========================================================
+**
** Switch sync mode for current job and it's target
**
**==========================================================
*/
-static void ncr_setsync (ncb_p np, ccb_p cp, u_char sxfer)
+static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer)
{
struct scsi_xfer *xp;
tcb_p tp;
+ int div;
u_char target = INB (nc_ctest0) & 0x0f;
assert (cp);
@@ -4849,24 +5391,43 @@ static void ncr_setsync (ncb_p np, ccb_p cp, u_char sxfer)
assert (target == (xp->sc_link->target & 0x0f));
tp = &np->target[target];
- tp->period= sxfer&0x1f ? ((sxfer>>5)+4) * np->ns_sync : 0xffff;
- if (tp->sval == sxfer) return;
+ if (!scntl3 || !(sxfer & 0x1f))
+ scntl3 = np->rv_scntl3;
+ scntl3 = (scntl3 & 0xf0) | (tp->wval & EWS) | (np->rv_scntl3 & 0x07);
+
+ /*
+ ** Deduce the value of controller sync period from scntl3.
+ ** period is in tenths of nano-seconds.
+ */
+
+ div = ((scntl3 >> 4) & 0x7);
+ if ((sxfer & 0x1f) && div)
+ tp->period = (((sxfer>>5)+4)*div_10M[div-1])/np->clock_khz;
+ else
+ tp->period = 0xffff;
+
+ /*
+ ** Stop there if sync parameters are unchanged
+ */
+
+ if (tp->sval == sxfer && tp->wval == scntl3) return;
tp->sval = sxfer;
+ tp->wval = scntl3;
/*
** Bells and whistles ;-)
*/
PRINT_ADDR(xp);
if (sxfer & 0x1f) {
- unsigned f10 = 10000 << (tp->widedone ? tp->widedone -1 : 0);
+ unsigned f10 = 100000 << (tp->widedone ? tp->widedone -1 : 0);
unsigned mb10 = (f10 + tp->period/2) / tp->period;
/*
** Disable extended Sreq/Sack filtering
*/
- if (tp->period <= 200) OUTB (nc_stest2, 0);
+ if (tp->period <= 2000) OUTOFFB (nc_stest2, EXT);
printf ("%d.%d MB/s (%d ns, offset %d)\n",
- mb10 / 10, mb10 % 10, tp->period, sxfer & 0x1f);
+ mb10 / 10, mb10 % 10, tp->period / 10, sxfer & 0x1f);
} else printf ("asynchronous.\n");
/*
@@ -4874,30 +5435,37 @@ static void ncr_setsync (ncb_p np, ccb_p cp, u_char sxfer)
*/
OUTB (nc_sxfer, sxfer);
np->sync_st = sxfer;
+ OUTB (nc_scntl3, scntl3);
+ np->wide_st = scntl3;
/*
** patch ALL ccbs of this target.
*/
- for (cp = &np->ccb; cp; cp = cp->link_ccb) {
+ for (cp = np->ccb; cp; cp = cp->link_ccb) {
if (!cp->xfer) continue;
if (cp->xfer->sc_link->target != target) continue;
cp->sync_status = sxfer;
+ cp->wide_status = scntl3;
};
}
/*==========================================================
**
** Switch wide mode for current job and it's target
+** SCSI specs say: a SCSI device that accepts a WDTR
+** message shall reset the synchronous agreement to
+** asynchronous mode.
**
**==========================================================
*/
-static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide)
+static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide, u_char ack)
{
struct scsi_xfer *xp;
u_short target = INB (nc_ctest0) & 0x0f;
tcb_p tp;
- u_char scntl3 = np->rv_scntl3 | (wide ? EWS : 0);
+ u_char scntl3;
+ u_char sxfer;
assert (cp);
if (!cp) return;
@@ -4909,28 +5477,41 @@ static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide)
tp = &np->target[target];
tp->widedone = wide+1;
- if (tp->wval == scntl3) return;
+ scntl3 = (tp->wval & (~EWS)) | (wide ? EWS : 0);
+
+ sxfer = ack ? 0 : tp->sval;
+
+ /*
+ ** Stop there if sync/wide parameters are unchanged
+ */
+ if (tp->sval == sxfer && tp->wval == scntl3) return;
+ tp->sval = sxfer;
tp->wval = scntl3;
/*
** Bells and whistles ;-)
*/
PRINT_ADDR(xp);
- printf ("WIDE SCSI %sabled\n",
- (scntl3 & EWS) ? "(16 bit) en" : "dis");
+ if (scntl3 & EWS)
+ printf ("WIDE SCSI (16 bit) enabled\n");
+ else
+ printf ("WIDE SCSI disabled\n");
/*
** set actual value and sync_status
*/
+ OUTB (nc_sxfer, sxfer);
+ np->sync_st = sxfer;
OUTB (nc_scntl3, scntl3);
np->wide_st = scntl3;
/*
** patch ALL ccbs of this target.
*/
- for (cp = &np->ccb; cp; cp = cp->link_ccb) {
+ for (cp = np->ccb; cp; cp = cp->link_ccb) {
if (!cp->xfer) continue;
if (cp->xfer->sc_link->target != target) continue;
+ cp->sync_status = sxfer;
cp->wide_status = scntl3;
};
}
@@ -4945,17 +5526,16 @@ static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide)
static void ncr_setmaxtags (tcb_p tp, u_long usrtags)
{
int l;
- tp->usrtags = usrtags;
for (l=0; l<MAX_LUN; l++) {
lcb_p lp;
if (!tp) break;
lp=tp->lp[l];
if (!lp) continue;
- ncr_settags (tp, lp);
+ ncr_settags (tp, lp, usrtags);
};
}
-static void ncr_settags (tcb_p tp, lcb_p lp)
+static void ncr_settags (tcb_p tp, lcb_p lp, u_long usrtags)
{
u_char reqtags, tmp;
@@ -4966,14 +5546,13 @@ static void ncr_settags (tcb_p tp, lcb_p lp)
** only disk devices
** only if enabled by user ..
*/
- if ((tp->inqdata[7] & INQ7_QUEUE) == 0) {
- tp->usrtags=0;
- }
- if (tp->quirks & QUIRK_NOTAGS) {
- tp->usrtags = 0;
+ if ((tp->inqdata[0] & 0x1f) != 0x00
+ || (tp->inqdata[7] & INQ7_QUEUE) == 0
+ || (tp->quirks & QUIRK_NOTAGS) != 0) {
+ usrtags=0;
}
- if (tp->usrtags && ((tp->inqdata[0] & 0x1f) == 0x00)) {
- reqtags = tp->usrtags;
+ if (usrtags) {
+ reqtags = usrtags;
if (lp->actlink <= 1)
lp->usetags=reqtags;
} else {
@@ -4995,6 +5574,8 @@ static void ncr_settags (tcb_p tp, lcb_p lp)
tmp = lp->actlink;
if (tmp < reqtags) tmp = reqtags;
lp->reqccbs = tmp;
+ if (lp->reqlink < lp->reqccbs)
+ lp->reqlink = lp->reqccbs;
}
/*----------------------------------------------------
@@ -5027,7 +5608,9 @@ static void ncr_usercmd (ncb_p np)
break;
for (t=0; t<MAX_TARGET; t++) {
if (!((np->user.target>>t)&1)) continue;
- ncr_setmaxtags (&np->target[t], np->user.data);
+ tp = &np->target[t];
+ tp->usrtags = np->user.data;
+ ncr_setmaxtags (tp, tp->usrtags);
};
break;
@@ -5079,9 +5662,14 @@ static void ncr_usercmd (ncb_p np)
**----------------------------------------------------------
*/
-static void ncr_timeout (ncb_p np)
+static void ncr_timeout (void *arg)
{
+ ncb_p np = arg;
+#ifdef __OpenBSD__
u_long thistime = mono_time.tv_sec;
+#else
+ u_long thistime = time.tv_sec;
+#endif
u_long step = np->ticks;
u_long count = 0;
long signed t;
@@ -5128,7 +5716,7 @@ static void ncr_timeout (ncb_p np)
**----------------------------------------------------
*/
- for (cp=&np->ccb; cp; cp=cp->link_ccb) {
+ for (cp=np->ccb; cp; cp=cp->link_ccb) {
/*
** look for timed out ccbs.
*/
@@ -5174,7 +5762,11 @@ static void ncr_timeout (ncb_p np)
splx (oldspl);
}
- timeout (TIMEOUT ncr_timeout, (caddr_t) np, step ? step : 1);
+#ifdef __FreeBSD__
+ np->timeout_ch = timeout (ncr_timeout, (caddr_t) np, step ? step : 1);
+#else
+ timeout (ncr_timeout, (caddr_t) np, step ? step : 1);
+#endif
if (INB(nc_istat) & (INTF|SIP|DIP)) {
@@ -5192,6 +5784,85 @@ static void ncr_timeout (ncb_p np)
/*==========================================================
**
+** log message for real hard errors
+**
+** "ncr0 targ 0?: ERROR (ds:si) (so-si-sd) (sxfer/scntl3) @ name (dsp:dbc)."
+** " reg: r0 r1 r2 r3 r4 r5 r6 ..... rf."
+**
+** exception register:
+** ds: dstat
+** si: sist
+**
+** SCSI bus lines:
+** so: control lines as driver by NCR.
+** si: control lines as seen by NCR.
+** sd: scsi data lines as seen by NCR.
+**
+** wide/fastmode:
+** sxfer: (see the manual)
+** scntl3: (see the manual)
+**
+** current script command:
+** dsp: script adress (relative to start of script).
+** dbc: first word of script command.
+**
+** First 16 register of the chip:
+** r0..rf
+**
+**==========================================================
+*/
+
+static void ncr_log_hard_error(ncb_p np, u_short sist, u_char dstat)
+{
+ u_int32_t dsp;
+ int script_ofs;
+ int script_size;
+ char *script_name;
+ u_char *script_base;
+ int i;
+
+ dsp = INL (nc_dsp);
+
+ if (np->p_script < dsp &&
+ dsp <= np->p_script + sizeof(struct script)) {
+ script_ofs = dsp - np->p_script;
+ script_size = sizeof(struct script);
+ script_base = (u_char *) np->script;
+ script_name = "script";
+ }
+ else if (np->p_scripth < dsp &&
+ dsp <= np->p_scripth + sizeof(struct scripth)) {
+ script_ofs = dsp - np->p_scripth;
+ script_size = sizeof(struct scripth);
+ script_base = (u_char *) np->scripth;
+ script_name = "scripth";
+ } else {
+ script_ofs = dsp;
+ script_size = 0;
+ script_base = 0;
+ script_name = "mem";
+ }
+
+ printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ (%s %x:%08x).\n",
+ ncr_name (np), (unsigned)INB (nc_ctest0)&0x0f, dstat, sist,
+ (unsigned)INB (nc_socl), (unsigned)INB (nc_sbcl), (unsigned)INB (nc_sbdl),
+ (unsigned)INB (nc_sxfer),(unsigned)INB (nc_scntl3), script_name, script_ofs,
+ (unsigned)INL (nc_dbc));
+
+ if (((script_ofs & 3) == 0) &&
+ (unsigned)script_ofs < script_size) {
+ printf ("%s: script cmd = %08x\n", ncr_name(np),
+ (int)READSCRIPT_OFF(script_base, script_ofs));
+ }
+
+ printf ("%s: regdump:", ncr_name(np));
+ for (i=0; i<16;i++)
+ printf (" %02x", (unsigned)INB_OFF(i));
+ printf (".\n");
+}
+
+/*==========================================================
+**
**
** ncr chip exception handler.
**
@@ -5201,10 +5872,8 @@ static void ncr_timeout (ncb_p np)
void ncr_exception (ncb_p np)
{
- U_INT8 istat, dstat;
- U_INT16 sist;
- U_INT32 dsp, dsa;
- int i, script_ofs;
+ u_int8_t istat, dstat;
+ u_int16_t sist;
/*
** interrupt on the fly ?
@@ -5224,7 +5893,7 @@ void ncr_exception (ncb_p np)
** Never test for an error condition you don't know how to handle.
*/
- sist = (istat & SIP) ? INW (nc_sist) : 0;
+ sist = (istat & SIP) ? INW (nc_sist) : 0;
dstat = (istat & DIP) ? INB (nc_dstat) : 0;
np->profile.num_int++;
@@ -5275,7 +5944,7 @@ void ncr_exception (ncb_p np)
if ((sist & MA) &&
!(sist & (STO|GEN|HTH|SGE|UDC|RST|PAR)) &&
!(dstat & (MDPE|BF|ABRT|SIR|IID))) {
- ncr_int_ma (np);
+ ncr_int_ma (np, dstat);
return;
};
@@ -5310,70 +5979,32 @@ void ncr_exception (ncb_p np)
};
/*========================================
+ ** log message for real hard errors
+ **========================================
+ */
+
+ ncr_log_hard_error(np, sist, dstat);
+
+ /*========================================
** do the register dump
**========================================
*/
+#ifdef __OpenBSD__
if (mono_time.tv_sec - np->regtime.tv_sec>10) {
int i;
np->regtime = mono_time;
+#else
+ if (time.tv_sec - np->regtime.tv_sec>10) {
+ int i;
+ gettime(&np->regtime);
+#endif
for (i=0; i<sizeof(np->regdump); i++)
((char*)&np->regdump)[i] = INB_OFF(i);
np->regdump.nc_dstat = dstat;
np->regdump.nc_sist = sist;
};
- /*=========================================
- ** log message for real hard errors
- **=========================================
-
- "ncr0 targ 0?: ERROR (ds:si) (so-si-sd) (sxfer/scntl3) @ (dsp:dbc)."
- " reg: r0 r1 r2 r3 r4 r5 r6 ..... rf."
-
- exception register:
- ds: dstat
- si: sist
-
- SCSI bus lines:
- so: control lines as driver by NCR.
- si: control lines as seen by NCR.
- sd: scsi data lines as seen by NCR.
-
- wide/fastmode:
- sxfer: (see the manual)
- scntl3: (see the manual)
-
- current script command:
- dsp: script adress (relative to start of script).
- dbc: first word of script command.
-
- First 16 register of the chip:
- r0..rf
-
- =============================================
- */
-
- dsp = (unsigned) INL (nc_dsp);
- dsa = (unsigned) INL (nc_dsa);
-
- script_ofs = dsp - np->p_script;
-
- printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ (%x:%08x).\n",
- ncr_name (np), INB (nc_ctest0)&0x0f, dstat, sist,
- INB (nc_socl), INB (nc_sbcl), INB (nc_sbdl),
- INB (nc_sxfer),INB (nc_scntl3), script_ofs,
- (unsigned) INL (nc_dbc));
-
- if (((script_ofs & 3) == 0) &&
- (unsigned)script_ofs < sizeof(struct script)) {
- printf ("\tscript cmd = %08x\n",
- *(ncrcmd *)((char*)np->script +script_ofs));
- }
-
- printf ("\treg:\t");
- for (i=0; i<16;i++)
- printf (" %02x", INB_OFF(i));
- printf (".\n");
/*----------------------------------------
** clean up the dma fifo
@@ -5468,7 +6099,7 @@ void ncr_exception (ncb_p np)
** @RECOVER@ HTH, SGE, ABRT.
**
** We should try to recover from these interrupts.
-** They may occur if there are problems with synch transfers, or
+** They may occur if there are problems with synch transfers, or
** if targets are switched on or off while the driver is running.
*/
@@ -5502,7 +6133,11 @@ void ncr_exception (ncb_p np)
if (i%16==15) printf (".\n");
};
- untimeout (TIMEOUT ncr_timeout, (caddr_t) np);
+#ifdef __FreeBSD__
+ untimeout (ncr_timeout, (caddr_t) np, np->timeout_ch);
+#else
+ untimeout (ncr_timeout, (caddr_t) np);
+#endif
printf ("%s: halted!\n", ncr_name(np));
/*
@@ -5555,7 +6190,7 @@ void ncr_int_sto (ncb_p np)
*/
dsa = INL (nc_dsa);
- cp = &np->ccb;
+ cp = np->ccb;
while (cp && (CCB_PHYS (cp, phys) != dsa))
cp = cp->link_ccb;
@@ -5569,12 +6204,12 @@ void ncr_int_sto (ncb_p np)
*/
scratcha = INL (nc_scratcha);
- diff = scratcha - NCB_SCRIPT_PHYS (np, tryloop);
+ diff = scratcha - NCB_SCRIPTH_PHYS (np, tryloop);
/* assert ((diff <= MAX_START * 20) && !(diff % 20));*/
if ((diff <= MAX_START * 20) && !(diff % 20)) {
- np->script->startpos[0] = SCR_BO(scratcha);
+ WRITESCRIPT(startpos[0], scratcha);
OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, start));
return;
};
@@ -5595,18 +6230,19 @@ void ncr_int_sto (ncb_p np)
**----------------------------------------------------------
*/
-static void ncr_int_ma (ncb_p np)
+static void ncr_int_ma (ncb_p np, u_char dstat)
{
- U_INT32 dbc;
- U_INT32 rest;
- U_INT32 dsa;
- U_INT32 dsp;
- U_INT32 nxtdsp;
- U_INT32 *vdsp;
- U_INT32 oadr, olen;
- U_INT32 *tblp;
+ u_int32_t dbc;
+ u_int32_t rest;
+ u_int32_t dsa;
+ u_int32_t dsp;
+ u_int32_t nxtdsp;
+ void *vdsp_base;
+ size_t vdsp_off;
+ u_int32_t oadr, olen;
+ u_int32_t *tblp;
ncrcmd *newcmd;
- U_INT32 cmd, sbcl, delta, ss0, ss2;
+ u_int32_t cmd, sbcl, delta, ss0, ss2, ctest5;
ccb_p cp;
dsp = INL (nc_dsp);
@@ -5618,7 +6254,13 @@ static void ncr_int_ma (ncb_p np)
cmd = dbc >> 24;
rest= dbc & 0xffffff;
- delta=(INB (nc_dfifo) - rest) & 0x7f;
+
+ ctest5 = (np->rv_ctest5 & DFS) ? INB (nc_ctest5) : 0;
+ if (ctest5 & DFS)
+ delta=(((ctest5<<8) | (INB (nc_dfifo) & 0xff)) - rest) & 0x3ff;
+ else
+ delta=(INB (nc_dfifo) - rest) & 0x7f;
+
/*
** The data in the dma fifo has not been transfered to
@@ -5627,7 +6269,7 @@ static void ncr_int_ma (ncb_p np)
** Check the sstat2 register in case of wide transfer.
*/
- if (! (INB(nc_dstat) & DFE)) rest += delta;
+ if (!(dstat & DFE)) rest += delta;
if (ss0 & OLF) rest++;
if (ss0 & ORF) rest++;
if (INB(nc_scntl3) & EWS) {
@@ -5641,18 +6283,18 @@ static void ncr_int_ma (ncb_p np)
** locate matching cp
*/
dsa = INL (nc_dsa);
- cp = &np->ccb;
+ cp = np->ccb;
while (cp && (CCB_PHYS (cp, phys) != dsa))
cp = cp->link_ccb;
if (!cp) {
- printf ("%s: SCSI phase error fixup: CCB already dequeued (0x%08lx)\n",
- ncr_name (np), (u_long) np->header.cp);
+ printf ("%s: SCSI phase error fixup: CCB already dequeued (%p)\n",
+ ncr_name (np), np->header.cp);
return;
}
if (cp != np->header.cp) {
- printf ("%s: SCSI phase error fixup: CCB address mismatch (0x%08lx != 0x%08lx) np.ccb = %p\n",
- ncr_name (np), (u_long) cp, (u_long) np->header.cp, &np->ccb);
+ printf ("%s: SCSI phase error fixup: CCB address mismatch (0x%08lx != 0x%08lx) np->ccb = %p\n",
+ ncr_name (np), (u_long) cp, (u_long) np->header.cp, np->ccb);
/* return;*/
}
@@ -5662,13 +6304,21 @@ static void ncr_int_ma (ncb_p np)
*/
if (dsp == vtophys (&cp->patch[2])) {
- vdsp = &cp->patch[0];
- nxtdsp = SCR_BO(vdsp[3]);
+ vdsp_base = cp;
+ vdsp_off = offsetof(struct ccb, patch[0]);
+ nxtdsp = READSCRIPT_OFF(vdsp_base, vdsp_off + 3*4);
} else if (dsp == vtophys (&cp->patch[6])) {
- vdsp = &cp->patch[4];
- nxtdsp = SCR_BO(vdsp[3]);
+ vdsp_base = cp;
+ vdsp_off = offsetof(struct ccb, patch[4]);
+ nxtdsp = READSCRIPT_OFF(vdsp_base, vdsp_off + 3*4);
+ } else if (dsp > np->p_script &&
+ dsp <= np->p_script + sizeof(struct script)) {
+ vdsp_base = np->script;
+ vdsp_off = dsp - np->p_script - 8;
+ nxtdsp = dsp;
} else {
- vdsp = (U_INT32 *) ((char*)np->script - np->p_script + dsp -8);
+ vdsp_base = np->scripth;
+ vdsp_off = dsp - np->p_scripth - 8;
nxtdsp = dsp;
};
@@ -5681,29 +6331,29 @@ static void ncr_int_ma (ncb_p np)
(unsigned) rest, (unsigned) delta, ss0);
};
if (DEBUG_FLAGS & DEBUG_PHASE) {
- printf ("\nCP=%p CP2=%p DSP=%x NXT=%x VDSP=%p CMD=%x ",
+ printf ("\nCP=%p CP2=%p DSP=%x NXT=%x VDSP_BASE=%p VDSP_OFF=0x%x CMD=%x ",
cp, np->header.cp, (unsigned)dsp,
- (unsigned)nxtdsp, vdsp, cmd);
+ (unsigned)nxtdsp, vdsp_base, (unsigned)vdsp_off, cmd);
};
/*
** get old startaddress and old length.
*/
- oadr = SCR_BO(vdsp[1]);
+ oadr = READSCRIPT_OFF(vdsp_base, vdsp_off + 1*4);
if (cmd & 0x10) { /* Table indirect */
- tblp = (U_INT32 *) ((char*) &cp->phys + oadr);
+ tblp = (u_int32_t *) ((char*) &cp->phys + oadr);
olen = SCR_BO(tblp[0]);
oadr = SCR_BO(tblp[1]);
} else {
- tblp = (U_INT32 *) 0;
- olen = SCR_BO(vdsp[0]) & 0xffffff;
+ tblp = (u_int32_t *) 0;
+ olen = READSCRIPT_OFF(vdsp_base, vdsp_off) & 0xffffff;
};
if (DEBUG_FLAGS & DEBUG_PHASE) {
printf ("OCMD=%x\nTBLP=%p OLEN=%x OADR=%x\n",
- (unsigned) (SCR_BO(vdsp[0]) >> 24),
+ (unsigned) (READSCRIPT_OFF(vdsp_base, vdsp_off) >> 24),
tblp,
(unsigned) olen,
(unsigned) oadr);
@@ -5713,10 +6363,11 @@ static void ncr_int_ma (ncb_p np)
** if old phase not dataphase, leave here.
*/
- if (cmd != (SCR_BO(vdsp[0]) >> 24)) {
+ if (cmd != (READSCRIPT_OFF(vdsp_base, vdsp_off) >> 24)) {
PRINT_ADDR(cp->xfer);
printf ("internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n",
- (unsigned)cmd, (unsigned)SCR_BO(vdsp[0]) >> 24);
+ (unsigned)cmd,
+ (unsigned)READSCRIPT_OFF(vdsp_base, vdsp_off) >> 24);
return;
}
@@ -5762,7 +6413,10 @@ static void ncr_int_ma (ncb_p np)
*/
np->profile.num_break++;
OUTL (nc_temp, vtophys (newcmd));
- OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, dispatch));
+ if ((cmd & 7) == 0)
+ OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, dispatch));
+ else
+ OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, checkatn));
}
/*==========================================================
@@ -5793,6 +6447,7 @@ static int ncr_show_msg (u_char * msg)
void ncr_int_sir (ncb_p np)
{
+ u_char scntl3;
u_char chg, ofs, per, fak, wide;
u_char num = INB (nc_dsps);
ccb_p cp=0;
@@ -5812,7 +6467,7 @@ void ncr_int_sir (ncb_p np)
** lookup the ccb
*/
dsa = INL (nc_dsa);
- cp = &np->ccb;
+ cp = np->ccb;
while (cp && (CCB_PHYS (cp, phys) != dsa))
cp = cp->link_ccb;
@@ -5861,7 +6516,7 @@ void ncr_int_sir (ncb_p np)
if (DEBUG_FLAGS & DEBUG_RESTART)
printf ("+ restart job ..\n");
OUTL (nc_dsa, CCB_PHYS (cp, phys));
- OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, getcc));
+ OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, getcc));
return;
};
@@ -5869,7 +6524,7 @@ void ncr_int_sir (ncb_p np)
** no job, resume normal processing
*/
if (DEBUG_FLAGS & DEBUG_RESTART) printf (" -- remove trap\n");
- np->script->start0[0] = SCR_INT ^ IFFALSE (0);
+ WRITESCRIPT(start0[0], SCR_INT ^ IFFALSE (0));
break;
case SIR_SENSE_FAILED:
@@ -5895,7 +6550,7 @@ void ncr_int_sir (ncb_p np)
/*
** And patch code to restart it.
*/
- np->script->start0[0] = SCR_INT;
+ WRITESCRIPT(start0[0], SCR_INT);
break;
/*-----------------------------------------------------------------------------
@@ -5925,14 +6580,14 @@ void ncr_int_sir (ncb_p np)
**
** If we receive a negotiation message while not in HS_NEGOTIATE
** state, it's a target initiated negotiation. We prepare a
-** (hopefully) valid answer, set our parameters, and send back
+** (hopefully) valid answer, set our parameters, and send back
** this answer to the target.
**
** If the target doesn't fetch the answer (no message out phase),
** we assume the negotiation has failed, and fall back to default
** settings.
**
-** When we set the values, we adjust them in all ccbs belonging
+** When we set the values, we adjust them in all ccbs belonging
** to this target, in the controller's register, and in the "phys"
** field of the controller's struct ncb.
**
@@ -5992,11 +6647,11 @@ void ncr_int_sir (ncb_p np)
switch (cp->nego_status) {
case NS_SYNC:
- ncr_setsync (np, cp, 0xe0);
+ ncr_setsync (np, cp, 0, 0xe0);
break;
case NS_WIDE:
- ncr_setwide (np, cp, 0);
+ ncr_setwide (np, cp, 0, 0);
break;
};
@@ -6039,8 +6694,8 @@ void ncr_int_sir (ncb_p np)
** check values against driver limits.
*/
- if (per < np->ns_sync)
- {chg = 1; per = np->ns_sync;}
+ if (per < np->minsync)
+ {chg = 1; per = np->minsync;}
if (per < tp->minsync)
{chg = 1; per = tp->minsync;}
if (ofs > tp->maxoffs)
@@ -6049,23 +6704,27 @@ void ncr_int_sir (ncb_p np)
/*
** Check against controller limits.
*/
+
+ fak = 7;
+ scntl3 = 0;
if (ofs != 0) {
- fak = (4ul * per - 1) / np->ns_sync - 3;
- if (fak>7) {
+ ncr_getsync(np, per, &fak, &scntl3);
+ if (fak > 7) {
chg = 1;
ofs = 0;
}
}
if (ofs == 0) {
- fak = 7;
- per = 0;
+ fak = 7;
+ per = 0;
+ scntl3 = 0;
tp->minsync = 0;
}
if (DEBUG_FLAGS & DEBUG_NEGO) {
PRINT_ADDR(cp->xfer);
- printf ("sync: per=%d ofs=%d fak=%d chg=%d.\n",
- per, ofs, fak, chg);
+ printf ("sync: per=%d scntl3=0x%x ofs=%d fak=%d chg=%d.\n",
+ per, scntl3, ofs, fak, chg);
}
if (INB (HS_PRT) == HS_NEGOTIATE) {
@@ -6080,19 +6739,19 @@ void ncr_int_sir (ncb_p np)
/*
** Answer wasn't acceptable.
*/
- ncr_setsync (np, cp, 0xe0);
+ ncr_setsync (np, cp, 0, 0xe0);
OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad));
} else {
/*
** Answer is ok.
*/
- ncr_setsync (np, cp, (fak<<5)|ofs);
+ ncr_setsync (np,cp,scntl3,(fak<<5)|ofs);
OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack));
};
return;
case NS_WIDE:
- ncr_setwide (np, cp, 0);
+ ncr_setwide (np, cp, 0, 0);
break;
};
};
@@ -6102,7 +6761,7 @@ void ncr_int_sir (ncb_p np)
** prepare an answer message
*/
- ncr_setsync (np, cp, (fak<<5)|ofs);
+ ncr_setsync (np, cp, scntl3, (fak<<5)|ofs);
np->msgout[0] = M_EXTENDED;
np->msgout[1] = 3;
@@ -6177,19 +6836,19 @@ void ncr_int_sir (ncb_p np)
/*
** Answer wasn't acceptable.
*/
- ncr_setwide (np, cp, 0);
+ ncr_setwide (np, cp, 0, 1);
OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad));
} else {
/*
** Answer is ok.
*/
- ncr_setwide (np, cp, wide);
+ ncr_setwide (np, cp, wide, 1);
OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack));
};
return;
case NS_SYNC:
- ncr_setsync (np, cp, 0xe0);
+ ncr_setsync (np, cp, 0, 0xe0);
break;
};
};
@@ -6199,7 +6858,7 @@ void ncr_int_sir (ncb_p np)
** prepare an answer message
*/
- ncr_setwide (np, cp, wide);
+ ncr_setwide (np, cp, wide, 1);
np->msgout[0] = M_EXTENDED;
np->msgout[1] = 2;
@@ -6316,7 +6975,7 @@ void ncr_int_sir (ncb_p np)
PRINT_ADDR(cp->xfer);
printf ("queue full.\n");
- np->script->start1[0] = SCR_INT;
+ WRITESCRIPT(start1[0], SCR_INT);
/*
** Try to disable tagged transfers.
@@ -6344,7 +7003,7 @@ void ncr_int_sir (ncb_p np)
/*
** Look for a disconnected job.
*/
- cp = &np->ccb;
+ cp = np->ccb;
while (cp && cp->host_status != HS_DISCONNECT)
cp = cp->link_ccb;
@@ -6364,7 +7023,7 @@ void ncr_int_sir (ncb_p np)
*/
printf ("%s: queue empty.\n", ncr_name (np));
- np->script->start1[0] = SCR_INT ^ IFFALSE (0);
+ WRITESCRIPT(start1[0], SCR_INT ^ IFFALSE (0));
break;
};
@@ -6387,6 +7046,7 @@ static ccb_p ncr_get_ccb
lcb_p lp;
ccb_p cp = (ccb_p) 0;
int oldspl;
+
oldspl = splbio();
/*
** Lun structure available ?
@@ -6409,7 +7069,7 @@ static ccb_p ncr_get_ccb
** if nothing available, take the default.
*/
- if (!cp) cp = &np->ccb;
+ if (!cp) cp = np->ccb;
/*
** Wait until available.
@@ -6450,7 +7110,7 @@ void ncr_free_ccb (ncb_p np, ccb_p cp, int flags)
cp -> host_status = HS_IDLE;
cp -> magic = 0;
- if (cp == &np->ccb)
+ if (cp == np->ccb)
wakeup ((caddr_t) cp);
}
@@ -6484,10 +7144,11 @@ static void ncr_alloc_ccb (ncb_p np, u_long target, u_long lun)
tp->jump_tcb.l_cmd = SCR_BO((SCR_JUMP^IFFALSE (DATA (0x80 + target))));
tp->jump_tcb.l_paddr = np->jump_tcb.l_paddr;
- tp->getscr[0] = SCR_BO(SCR_COPY (1));
+ tp->getscr[0] =
+ (np->features & FE_PFEN)? SCR_BO(SCR_COPY(1)) : SCR_BO(SCR_COPY_F(1));
tp->getscr[1] = SCR_BO(vtophys (&tp->sval));
tp->getscr[2] = SCR_BO(np->paddr + offsetof (struct ncr_reg, nc_sxfer));
- tp->getscr[3] = SCR_BO(SCR_COPY (1));
+ tp->getscr[3] = tp->getscr[0];
tp->getscr[4] = SCR_BO(vtophys (&tp->wval));
tp->getscr[5] = SCR_BO(np->paddr + offsetof (struct ncr_reg, nc_scntl3));
@@ -6500,10 +7161,11 @@ static void ncr_alloc_ccb (ncb_p np, u_long target, u_long lun)
tp->call_lun.l_paddr = SCR_BO(NCB_SCRIPT_PHYS (np, resel_lun));
tp->jump_lcb.l_cmd = SCR_BO((SCR_JUMP));
- tp->jump_lcb.l_paddr = SCR_BO(NCB_SCRIPT_PHYS (np, abort));
+ tp->jump_lcb.l_paddr = SCR_BO(NCB_SCRIPTH_PHYS (np, abort));
np->jump_tcb.l_paddr = SCR_BO(vtophys (&tp->jump_tcb));
- ncr_setmaxtags (tp, SCSI_NCR_DFLT_TAGS);
+ tp->usrtags = SCSI_NCR_DFLT_TAGS;
+ ncr_setmaxtags (tp, tp->usrtags);
}
/*
@@ -6528,7 +7190,7 @@ static void ncr_alloc_ccb (ncb_p np, u_long target, u_long lun)
lp->call_tag.l_paddr = SCR_BO(NCB_SCRIPT_PHYS (np, resel_tag));
lp->jump_ccb.l_cmd = SCR_BO((SCR_JUMP));
- lp->jump_ccb.l_paddr = SCR_BO(NCB_SCRIPT_PHYS (np, aborttag));
+ lp->jump_ccb.l_paddr = SCR_BO(NCB_SCRIPTH_PHYS (np, aborttag));
lp->actlink = 1;
@@ -6592,8 +7254,8 @@ static void ncr_alloc_ccb (ncb_p np, u_long target, u_long lun)
/*
** Chain into wakeup list
*/
- cp->link_ccb = np->ccb.link_ccb;
- np->ccb.link_ccb = cp;
+ cp->link_ccb = np->ccb->link_ccb;
+ np->ccb->link_ccb = cp;
/*
** Chain into CCB list
@@ -6626,17 +7288,17 @@ static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp)
if (!diff) return;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
if (diff > xp->sc_link->openings)
diff = xp->sc_link->openings;
xp->sc_link->openings -= diff;
-#else /* !(__NetBSD__ || __OpenBSD__) */
+#else
if (diff > xp->sc_link->opennings)
diff = xp->sc_link->opennings;
xp->sc_link->opennings -= diff;
-#endif /* __NetBSD__ || __OpenBSD__ */
+#endif
lp->actlink -= diff;
if (DEBUG_FLAGS & DEBUG_TAGS)
printf ("%s: actlink: diff=%d, new=%d, req=%d\n",
@@ -6650,11 +7312,7 @@ static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp)
if (lp->reqlink > lp->actlink) {
u_char diff = lp->reqlink - lp->actlink;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
xp->sc_link->openings += diff;
-#else /* !(__NetBSD__ || __OpenBSD__) */
- xp->sc_link->opennings += diff;
-#endif /* __NetBSD__ || __OpenBSD__ */
lp->actlink += diff;
wakeup ((caddr_t) xp->sc_link);
if (DEBUG_FLAGS & DEBUG_TAGS)
@@ -6693,7 +7351,7 @@ static int ncr_scatter
bzero (&phys->data, sizeof (phys->data));
if (!datalen) return (0);
- paddr = vtophys ((void *)vaddr);
+ paddr = vtophys (vaddr);
/*
** insert extra break points at a distance of chunk.
@@ -6708,7 +7366,7 @@ static int ncr_scatter
free = MAX_SCATTER - 1;
- if (vaddr & (NBPG-1)) free -= datalen / NBPG;
+ if (vaddr & PAGE_MASK) free -= datalen / PAGE_SIZE;
if (free>1)
while ((chunk * free >= 2 * datalen) && (chunk>=1024))
@@ -6737,7 +7395,7 @@ static int ncr_scatter
/*
** continue this segment
*/
- pnext = (paddr & (~(NBPG - 1))) + NBPG;
+ pnext = (paddr & (~PAGE_MASK)) + PAGE_SIZE;
/*
** Compute max size
@@ -6751,7 +7409,7 @@ static int ncr_scatter
vaddr += size;
csize -= size;
datalen -= size;
- paddr = vtophys ((void *)vaddr);
+ paddr = vtophys (vaddr);
};
if(DEBUG_FLAGS & DEBUG_SCATTER)
@@ -6786,10 +7444,10 @@ static int ncr_scatter
**==========================================================
*/
-#ifndef NCR_IOMAPPED
+#if !defined(NCR_IOMAPPED) || defined(__OpenBSD__)
static int ncr_regtest (struct ncb* np)
{
- register volatile u_long data;
+ register volatile u_int32_t data;
/*
** ncr registers may NOT be cached.
** write 0xffffffff to a read only register area,
@@ -6813,16 +7471,21 @@ static int ncr_regtest (struct ncb* np)
static int ncr_snooptest (struct ncb* np)
{
- u_long ncr_rd, ncr_wr, ncr_bk, host_rd, host_wr, pc, err=0;
- int i;
-#ifndef NCR_IOMAPPED
- err |= ncr_regtest (np);
- if (err) return (err);
+ u_int32_t ncr_rd, ncr_wr, ncr_bk, host_rd, host_wr, pc;
+ int i, err=0;
+#if !defined(NCR_IOMAPPED) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
+ if (!np->sc_iomapped)
+#endif
+ {
+ err |= ncr_regtest (np);
+ if (err) return (err);
+ }
#endif
/*
** init
*/
- pc = NCB_SCRIPT_PHYS (np, snooptest);
+ pc = NCB_SCRIPTH_PHYS (np, snooptest);
host_wr = 1;
ncr_wr = 2;
/*
@@ -6866,11 +7529,11 @@ static int ncr_snooptest (struct ncb* np)
/*
** Check termination position.
*/
- if (pc != NCB_SCRIPT_PHYS (np, snoopend)+8) {
+ if (pc != NCB_SCRIPTH_PHYS (np, snoopend)+8) {
printf ("CACHE TEST FAILED: script execution failed.\n");
- printf ("\tstart=%08lx, pc=%08lx, end=%08lx\n",
- NCB_SCRIPT_PHYS (np, snooptest), pc,
- NCB_SCRIPT_PHYS (np, snoopend) +8);
+ printf ("start=%08lx, pc=%08lx, end=%08lx\n",
+ (u_long) NCB_SCRIPTH_PHYS (np, snooptest), (u_long) pc,
+ (u_long) NCB_SCRIPTH_PHYS (np, snoopend) +8);
return (0x40);
};
/*
@@ -6921,7 +7584,11 @@ static void ncb_profile (ncb_p np, ccb_p cp)
int co, da, st, en, di, se, post,work,disc;
u_long diff;
+#ifdef __OpenBSD__
PROFILE.end = mono_time;
+#else
+ gettime(&PROFILE.end);
+#endif
st = ncr_delta (&PROFILE.start,&PROFILE.status);
if (st<0) return; /* status not reached */
@@ -6959,6 +7626,7 @@ static void ncb_profile (ncb_p np, ccb_p cp)
}
#undef PROFILE
+#ifdef __OpenBSD__
/*==========================================================
**
**
@@ -6970,8 +7638,6 @@ static void ncb_profile (ncb_p np, ccb_p cp)
**==========================================================
*/
-#ifndef NEW_SCSICONF
-
struct table_entry {
char * manufacturer;
char * model;
@@ -7017,12 +7683,12 @@ static u_long ncr_lookup(char * id)
return (p->info);
}
}
-#endif
+#endif /* __OpenBSD__ */
/*==========================================================
**
** Determine the ncr's clock frequency.
-** This is important for the negotiation
+** This is essential for the negotiation
** of the synchronous transfer rate.
**
**==========================================================
@@ -7030,18 +7696,45 @@ static u_long ncr_lookup(char * id)
** Note: we have to return the correct value.
** THERE IS NO SAVE DEFAULT VALUE.
**
-** We assume that all NCR based boards are delivered
-** with a 40Mhz clock. Because we have to divide
-** by an integer value greater than 3, only clock
-** frequencies of 40Mhz (/4) or 50MHz (/5) permit
-** the FAST-SCSI rate of 10MHz.
+** Most NCR/SYMBIOS boards are delivered with a 40 Mhz clock.
+** 53C860 and 53C875 rev. 1 support fast20 transfers but
+** do not have a clock doubler and so are provided with a
+** 80 MHz clock. All other fast20 boards incorporate a doubler
+** and so should be delivered with a 40 MHz clock.
+** The future fast40 chips (895/895) use a 40 Mhz base clock
+** and provide a clock quadrupler (160 Mhz). The code below
+** tries to deal as cleverly as possible with all this stuff.
**
**----------------------------------------------------------
*/
-#ifndef NCR_CLOCK
-# define NCR_CLOCK 40
-#endif /* NCR_CLOCK */
+/*
+ * Select NCR SCSI clock frequency
+ */
+static void ncr_selectclock(ncb_p np, u_char scntl3)
+{
+ if (np->multiplier < 2) {
+ OUTB(nc_scntl3, scntl3);
+ return;
+ }
+
+ if (bootverbose >= 2)
+ printf ("%s: enabling clock multiplier\n", ncr_name(np));
+
+ OUTB(nc_stest1, DBLEN); /* Enable clock multiplier */
+ if (np->multiplier > 2) { /* Poll bit 5 of stest4 for quadrupler */
+ int i = 20;
+ while (!(INB(nc_stest4) & LCKFRQ) && --i > 0)
+ DELAY(20);
+ if (!i)
+ printf("%s: the chip cannot lock the frequency\n", ncr_name(np));
+ } else /* Wait 20 micro-seconds for doubler */
+ DELAY(20);
+ OUTB(nc_stest3, HSC); /* Halt the scsi clock */
+ OUTB(nc_scntl3, scntl3);
+ OUTB(nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */
+ OUTB(nc_stest3, 0x00); /* Restart scsi clock */
+}
/*
* calculate NCR SCSI clock frequency (in KHz)
@@ -7051,18 +7744,18 @@ ncrgetfreq (ncb_p np, int gen)
{
int ms = 0;
/*
- * Measure GEN timer delay in order
+ * Measure GEN timer delay in order
* to calculate SCSI clock frequency
*
* This code will never execute too
- * many loop iterations (if DELAY is
+ * many loop iterations (if DELAY is
* reasonably correct). It could get
* too low a delay (too high a freq.)
- * if the CPU is slow executing the
+ * if the CPU is slow executing the
* loop for some reason (an NMI, for
* example). For this reason we will
- * if multiple measurements are to be
- * performed trust the higher delay
+ * if multiple measurements are to be
+ * performed trust the higher delay
* (lower frequency returned).
*/
OUTB (nc_stest1, 0); /* make sure clock doubler is OFF */
@@ -7084,25 +7777,26 @@ ncrgetfreq (ncb_p np, int gen)
*/
OUTB (nc_scntl3, 0);
- if (bootverbose)
+ if (bootverbose >= 2)
printf ("\tDelay (GEN=%d): %u msec\n", gen, ms);
/*
- * adjust for prescaler, and convert into KHz
+ * adjust for prescaler, and convert into KHz
*/
return ms ? ((1 << gen) * 4440) / ms : 0;
}
-static void ncr_getclock (ncb_p np)
+static void ncr_getclock (ncb_p np, u_char multiplier)
{
unsigned char scntl3;
unsigned char stest1;
scntl3 = INB(nc_scntl3);
stest1 = INB(nc_stest1);
-
+
+ np->multiplier = 1;
/* always false, except for 875 with clock doubler selected */
if ((stest1 & (DBLEN+DBLSEL)) == DBLEN+DBLSEL) {
- OUTB(nc_stest1, 0);
- scntl3 = 3;
+ np->multiplier = multiplier;
+ np->clock_khz = 40000 * multiplier;
} else {
if ((scntl3 & 7) == 0) {
unsigned f1, f2;
@@ -7111,7 +7805,7 @@ static void ncr_getclock (ncb_p np)
f1 = ncrgetfreq (np, 11);
f2 = ncrgetfreq (np, 11);
- if (bootverbose)
+ if (bootverbose >= 2)
printf ("\tNCR clock is %uKHz, %uKHz\n", f1, f2);
if (f1 > f2) f1 = f2; /* trust lower result */
if (f1 > 45000) {
@@ -7120,13 +7814,8 @@ static void ncr_getclock (ncb_p np)
scntl3 = 3; /* <45Mhz: assume 40MHz */
}
}
- }
-
- np->rv_scntl3 = ((scntl3 & 0x7) << 4) -0x20 + (scntl3 & 0x7);
-
- if (bootverbose) {
- printf ("\tinitial value of SCNTL3 = %02x, final = %02x\n",
- scntl3, np->rv_scntl3);
+ else if ((scntl3 & 7) == 5)
+ np->clock_khz = 80000; /* Probably a 875 rev. 1 ? */
}
}
@@ -7149,7 +7838,7 @@ struct tekram_eeprom_dev {
struct tekram_eeprom {
- struct tekram_eeprom_dev
+ struct tekram_eeprom_dev
dev[16];
u_char adaptid;
u_char adaptmode;
@@ -7213,7 +7902,7 @@ read_tekram_eeprom_reg (ncb_p np, int reg)
return result;
}
-static int
+static int
read_tekram_eeprom(ncb_p np, struct tekram_eeprom *buffer)
{
u_short *p = (u_short *) buffer;
diff --git a/sys/dev/pci/ncrreg.h b/sys/dev/pci/ncrreg.h
new file mode 100644
index 00000000000..e25ac4af03e
--- /dev/null
+++ b/sys/dev/pci/ncrreg.h
@@ -0,0 +1,665 @@
+/* $OpenBSD: ncrreg.h,v 1.1 1997/12/01 18:58:49 millert Exp $ */
+/* $NetBSD: ncrreg.h,v 1.14 1997/09/23 02:27:46 perry Exp $ */
+
+/**************************************************************************
+**
+** Id: ncrreg.h,v 1.11 1997/08/31 19:42:31 se Exp
+**
+** Device driver for the NCR 53C810 PCI-SCSI-Controller.
+**
+** FreeBSD / NetBSD / OpenBSD
+**
+**-------------------------------------------------------------------------
+**
+** Written for 386bsd and FreeBSD by
+** wolf@cologne.de Wolfgang Stanglmeier
+** se@mi.Uni-Koeln.de Stefan Esser
+**
+** Ported to NetBSD by
+** mycroft@gnu.ai.mit.edu
+**
+**-------------------------------------------------------------------------
+**
+** Copyright (c) 1994 Wolfgang Stanglmeier. 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.
+**
+***************************************************************************
+*/
+
+#ifndef __NCR_REG_H__
+#define __NCR_REG_H__
+
+/*==========================================================
+**
+** OS dependencies.
+**
+**==========================================================
+*/
+
+#ifdef __OpenBSD__
+#define ISSCRIPTRAMMAPPED(np) (np->scriptmapped)
+#else /*__OpenBSD__*/
+#define ISSCRIPTRAMMAPPED(np) (np->vaddr2)
+#endif /*__OpenBSD__*/
+
+/*-----------------------------------------------------------------
+**
+** The ncr 53c810 register structure.
+**
+**-----------------------------------------------------------------
+*/
+
+struct ncr_reg {
+/*00*/ u_int8_t nc_scntl0; /* full arb., ena parity, par->ATN */
+
+/*01*/ u_int8_t nc_scntl1; /* no reset */
+ #define ISCON 0x10 /* connected to scsi */
+ #define CRST 0x08 /* force reset */
+
+/*02*/ u_int8_t nc_scntl2; /* no disconnect expected */
+ #define SDU 0x80 /* cmd: disconnect will raise error */
+ #define CHM 0x40 /* sta: chained mode */
+ #define WSS 0x08 /* sta: wide scsi send [W]*/
+ #define WSR 0x01 /* sta: wide scsi received [W]*/
+
+/*03*/ u_int8_t nc_scntl3; /* cnf system clock dependent */
+ #define EWS 0x08 /* cmd: enable wide scsi [W]*/
+
+/*04*/ u_int8_t nc_scid; /* cnf host adapter scsi address */
+ #define RRE 0x40 /* r/w:e enable response to resel. */
+ #define SRE 0x20 /* r/w:e enable response to select */
+
+/*05*/ u_int8_t nc_sxfer; /* ### Sync speed and count */
+
+/*06*/ u_int8_t nc_sdid; /* ### Destination-ID */
+
+/*07*/ u_int8_t nc_gpreg; /* ??? IO-Pins */
+
+/*08*/ u_int8_t nc_sfbr; /* ### First byte in phase */
+
+/*09*/ u_int8_t nc_socl;
+ #define CREQ 0x80 /* r/w: SCSI-REQ */
+ #define CACK 0x40 /* r/w: SCSI-ACK */
+ #define CBSY 0x20 /* r/w: SCSI-BSY */
+ #define CSEL 0x10 /* r/w: SCSI-SEL */
+ #define CATN 0x08 /* r/w: SCSI-ATN */
+ #define CMSG 0x04 /* r/w: SCSI-MSG */
+ #define CC_D 0x02 /* r/w: SCSI-C_D */
+ #define CI_O 0x01 /* r/w: SCSI-I_O */
+
+/*0a*/ u_int8_t nc_ssid;
+
+/*0b*/ u_int8_t nc_sbcl;
+
+/*0c*/ u_int8_t nc_dstat;
+ #define DFE 0x80 /* sta: dma fifo empty */
+ #define MDPE 0x40 /* int: master data parity error */
+ #define BF 0x20 /* int: script: bus fault */
+ #define ABRT 0x10 /* int: script: command aborted */
+ #define SSI 0x08 /* int: script: single step */
+ #define SIR 0x04 /* int: script: interrupt instruct. */
+ #define IID 0x01 /* int: script: illegal instruct. */
+
+/*0d*/ u_int8_t nc_sstat0;
+ #define ILF 0x80 /* sta: data in SIDL register lsb */
+ #define ORF 0x40 /* sta: data in SODR register lsb */
+ #define OLF 0x20 /* sta: data in SODL register lsb */
+ #define AIP 0x10 /* sta: arbitration in progress */
+ #define LOA 0x08 /* sta: arbitration lost */
+ #define WOA 0x04 /* sta: arbitration won */
+ #define IRST 0x02 /* sta: scsi reset signal */
+ #define SDP 0x01 /* sta: scsi parity signal */
+
+/*0e*/ u_int8_t nc_sstat1;
+ #define FF3210 0xf0 /* sta: bytes in the scsi fifo */
+
+/*0f*/ u_int8_t nc_sstat2;
+ #define ILF1 0x80 /* sta: data in SIDL register msb[W]*/
+ #define ORF1 0x40 /* sta: data in SODR register msb[W]*/
+ #define OLF1 0x20 /* sta: data in SODL register msb[W]*/
+ #define LDSC 0x02 /* sta: disconnect & reconnect */
+
+/*10*/ u_int32_t nc_dsa; /* --> Base page */
+
+/*14*/ u_int8_t nc_istat; /* --> Main Command and status */
+ #define CABRT 0x80 /* cmd: abort current operation */
+ #define SRST 0x40 /* mod: reset chip */
+ #define SIGP 0x20 /* r/w: message from host to ncr */
+ #define SEM 0x10 /* r/w: message between host + ncr */
+ #define CON 0x08 /* sta: connected to scsi */
+ #define INTF 0x04 /* sta: int on the fly (reset by wr)*/
+ #define SIP 0x02 /* sta: scsi-interrupt */
+ #define DIP 0x01 /* sta: host/script interrupt */
+
+/*15*/ u_int8_t nc_15_;
+/*16*/ u_int8_t nc_16_;
+/*17*/ u_int8_t nc_17_;
+
+/*18*/ u_int8_t nc_ctest0;
+/*19*/ u_int8_t nc_ctest1;
+
+/*1a*/ u_int8_t nc_ctest2;
+ #define CSIGP 0x40
+
+/*1b*/ u_int8_t nc_ctest3;
+ #define FLF 0x08 /* cmd: flush dma fifo */
+ #define CLF 0x04 /* cmd: clear dma fifo */
+ #define FM 0x02 /* mod: fetch pin mode */
+ #define WRIE 0x01 /* mod: write and invalidate enable */
+
+/*1c*/ u_int32_t nc_temp; /* ### Temporary stack */
+
+/*20*/ u_int8_t nc_dfifo;
+/*21*/ u_int8_t nc_ctest4;
+ #define BDIS 0x80 /* mod: burst disable */
+ #define MPEE 0x08 /* mod: master parity error enable */
+
+/*22*/ u_int8_t nc_ctest5;
+ #define DFS 0x20 /* mod: dma fifo size */
+/*23*/ u_int8_t nc_ctest6;
+
+/*24*/ u_int32_t nc_dbc; /* ### Byte count and command */
+/*28*/ u_int32_t nc_dnad; /* ### Next command register */
+/*2c*/ u_int32_t nc_dsp; /* --> Script Pointer */
+/*30*/ u_int32_t nc_dsps; /* --> Script pointer save/opcode#2 */
+/*34*/ u_int32_t nc_scratcha; /* ??? Temporary register a */
+
+/*38*/ u_int8_t nc_dmode;
+ #define BL_2 0x80 /* mod: burst length shift value +2 */
+ #define BL_1 0x40 /* mod: burst length shift value +1 */
+ #define ERL 0x08 /* mod: enable read line */
+ #define ERMP 0x04 /* mod: enable read multiple */
+ #define BOF 0x02 /* mod: burst op code fetch */
+
+/*39*/ u_int8_t nc_dien;
+/*3a*/ u_int8_t nc_dwt;
+
+/*3b*/ u_int8_t nc_dcntl; /* --> Script execution control */
+ #define CLSE 0x80 /* mod: cache line size enable */
+ #define PFF 0x40 /* cmd: pre-fetch flush */
+ #define PFEN 0x20 /* mod: pre-fetch enable */
+ #define SSM 0x10 /* mod: single step mode */
+ #define IRQM 0x08 /* mod: irq mode (1 = totem pole !) */
+ #define STD 0x04 /* cmd: start dma mode */
+ #define IRQD 0x02 /* mod: irq disable */
+ #define NOCOM 0x01 /* cmd: protect sfbr while reselect */
+
+/*3c*/ u_int32_t nc_adder;
+
+/*40*/ u_int16_t nc_sien; /* -->: interrupt enable */
+/*42*/ u_int16_t nc_sist; /* <--: interrupt status */
+ #define STO 0x0400/* sta: timeout (select) */
+ #define GEN 0x0200/* sta: timeout (general) */
+ #define HTH 0x0100/* sta: timeout (handshake) */
+ #define MA 0x80 /* sta: phase mismatch */
+ #define CMP 0x40 /* sta: arbitration complete */
+ #define SEL 0x20 /* sta: selected by another device */
+ #define RSL 0x10 /* sta: reselected by another device*/
+ #define SGE 0x08 /* sta: gross error (over/underflow)*/
+ #define UDC 0x04 /* sta: unexpected disconnect */
+ #define RST 0x02 /* sta: scsi bus reset detected */
+ #define PAR 0x01 /* sta: scsi parity error */
+
+/*44*/ u_int8_t nc_slpar;
+/*45*/ u_int8_t nc_swide;
+/*46*/ u_int8_t nc_macntl;
+/*47*/ u_int8_t nc_gpcntl;
+/*48*/ u_int8_t nc_stime0; /* cmd: timeout for select&handshake*/
+/*49*/ u_int8_t nc_stime1; /* cmd: timeout user defined */
+/*4a*/ u_int16_t nc_respid; /* sta: Reselect-IDs */
+
+/*4c*/ u_int8_t nc_stest0;
+
+/*4d*/ u_int8_t nc_stest1;
+ #define DBLEN 0x08 /* clock doubler running */
+ #define DBLSEL 0x04 /* clock doubler selected */
+
+/*4e*/ u_int8_t nc_stest2;
+ #define ROF 0x40 /* reset scsi offset (after gross error!) */
+ #define EXT 0x02 /* extended filtering */
+
+/*4f*/ u_int8_t nc_stest3;
+ #define TE 0x80 /* c: tolerAnt enable */
+ #define HSC 0x20 /* c: Halt SCSI Clock */
+ #define CSF 0x02 /* c: clear scsi fifo */
+
+/*50*/ u_int16_t nc_sidl; /* Lowlevel: latched from scsi data */
+/*52*/ u_int8_t nc_stest4;
+ #define SMODE 0xc0 /* SCSI bus mode (895/6 only) */
+ #define SMODE_HVD 0x40 /* High Voltage Differential */
+ #define SMODE_SE 0x80 /* Single Ended */
+ #define SMODE_LVD 0xc0 /* Low Voltage Differential */
+ #define LCKFRQ 0x20 /* Frequency Lock (895/6 only) */
+
+/*53*/ u_int8_t nc_53_;
+/*54*/ u_int16_t nc_sodl; /* Lowlevel: data out to scsi data */
+/*56*/ u_int16_t nc_56_;
+/*58*/ u_int16_t nc_sbdl; /* Lowlevel: data from scsi data */
+/*5a*/ u_int16_t nc_5a_;
+/*5c*/ u_int8_t nc_scr0; /* Working register B */
+/*5d*/ u_int8_t nc_scr1; /* */
+/*5e*/ u_int8_t nc_scr2; /* */
+/*5f*/ u_int8_t nc_scr3; /* */
+/*60*/
+};
+
+/*-----------------------------------------------------------
+**
+** Utility macros for the script.
+**
+**-----------------------------------------------------------
+*/
+
+#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r))
+#define REG(r) REGJ (nc_, r)
+
+#ifndef TARGET_MODE
+#define TARGET_MODE 0
+#endif
+
+typedef u_int32_t ncrcmd;
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define SCR_BO(x) (((x) >> 24) | (((x) >> 8) & 0xff00) | \
+ ((x) << 24) | (((x) & 0xff00) << 8))
+#else
+#define SCR_BO(x) (x)
+#endif
+
+/*-----------------------------------------------------------
+**
+** SCSI phases
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_DATA_OUT 0x00000000
+#define SCR_DATA_IN 0x01000000
+#define SCR_COMMAND 0x02000000
+#define SCR_STATUS 0x03000000
+#define SCR_ILG_OUT 0x04000000
+#define SCR_ILG_IN 0x05000000
+#define SCR_MSG_OUT 0x06000000
+#define SCR_MSG_IN 0x07000000
+
+/*-----------------------------------------------------------
+**
+** Data transfer via SCSI.
+**
+**-----------------------------------------------------------
+**
+** MOVE_ABS (LEN)
+** <<start address>>
+**
+** MOVE_IND (LEN)
+** <<dnad_offset>>
+**
+** MOVE_TBL
+** <<dnad_offset>>
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_MOVE_ABS(l) ((0x08000000 ^ (TARGET_MODE << 1ul)) | (l))
+#define SCR_MOVE_IND(l) ((0x28000000 ^ (TARGET_MODE << 1ul)) | (l))
+#define SCR_MOVE_TBL (0x18000000 ^ (TARGET_MODE << 1ul))
+
+struct scr_tblmove {
+ u_int32_t size;
+ u_int32_t addr;
+};
+
+/*-----------------------------------------------------------
+**
+** Selection
+**
+**-----------------------------------------------------------
+**
+** SEL_ABS | SCR_ID (0..7) [ | REL_JMP]
+** <<alternate_address>>
+**
+** SEL_TBL | << dnad_offset>> [ | REL_JMP]
+** <<alternate_address>>
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_SEL_ABS 0x40000000
+#define SCR_SEL_ABS_ATN 0x41000000
+#define SCR_SEL_TBL 0x42000000
+#define SCR_SEL_TBL_ATN 0x43000000
+
+struct scr_tblsel {
+ u_int8_t sel_0;
+ u_int8_t sel_sxfer;
+ u_int8_t sel_id;
+ u_int8_t sel_scntl3;
+};
+
+#define SCR_JMP_REL 0x04000000
+#define SCR_ID(id) (((u_int32_t)(id)) << 16)
+
+/*-----------------------------------------------------------
+**
+** Waiting for Disconnect or Reselect
+**
+**-----------------------------------------------------------
+**
+** WAIT_DISC
+** dummy: <<alternate_address>>
+**
+** WAIT_RESEL
+** <<alternate_address>>
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_WAIT_DISC 0x48000000
+#define SCR_WAIT_RESEL 0x50000000
+
+/*-----------------------------------------------------------
+**
+** Bit Set / Reset
+**
+**-----------------------------------------------------------
+**
+** SET (flags {|.. })
+**
+** CLR (flags {|.. })
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_SET(f) (0x58000000 | (f))
+#define SCR_CLR(f) (0x60000000 | (f))
+
+#define SCR_CARRY 0x00000400
+#define SCR_TRG 0x00000200
+#define SCR_ACK 0x00000040
+#define SCR_ATN 0x00000008
+
+
+/*-----------------------------------------------------------
+**
+** Memory to memory move
+**
+**-----------------------------------------------------------
+**
+** COPY (bytecount)
+** << source_address >>
+** << destination_address >>
+**
+** SCR_COPY sets the NO FLUSH option by default.
+** SCR_COPY_F does not set this option.
+**
+** For chips which do not support this option,
+** ncr_copy_and_bind() will remove this bit.
+**-----------------------------------------------------------
+*/
+
+#define SCR_NO_FLUSH 0x01000000
+
+#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n))
+#define SCR_COPY_F(n) (0xc0000000 | (n))
+
+
+/*-----------------------------------------------------------
+**
+** Register move and binary operations
+**
+**-----------------------------------------------------------
+**
+** SFBR_REG (reg, op, data) reg = SFBR op data
+** << 0 >>
+**
+** REG_SFBR (reg, op, data) SFBR = reg op data
+** << 0 >>
+**
+** REG_REG (reg, op, data) reg = reg op data
+** << 0 >>
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_REG_OFS(ofs) ((ofs) << 16ul)
+
+#define SCR_SFBR_REG(reg,op,data) \
+ (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | ((data)<<8ul))
+
+#define SCR_REG_SFBR(reg,op,data) \
+ (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | ((data)<<8ul))
+
+#define SCR_REG_REG(reg,op,data) \
+ (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | ((data)<<8ul))
+
+
+#define SCR_LOAD 0x00000000
+#define SCR_SHL 0x01000000
+#define SCR_OR 0x02000000
+#define SCR_XOR 0x03000000
+#define SCR_AND 0x04000000
+#define SCR_SHR 0x05000000
+#define SCR_ADD 0x06000000
+#define SCR_ADDC 0x07000000
+
+/*-----------------------------------------------------------
+**
+** FROM_REG (reg) reg = SFBR
+** << 0 >>
+**
+** TO_REG (reg) SFBR = reg
+** << 0 >>
+**
+** LOAD_REG (reg, data) reg = <data>
+** << 0 >>
+**
+** LOAD_SFBR(data) SFBR = <data>
+** << 0 >>
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_FROM_REG(reg) \
+ SCR_REG_SFBR(reg,SCR_OR,0)
+
+#define SCR_TO_REG(reg) \
+ SCR_SFBR_REG(reg,SCR_OR,0)
+
+#define SCR_LOAD_REG(reg,data) \
+ SCR_REG_REG(reg,SCR_LOAD,data)
+
+#define SCR_LOAD_SFBR(data) \
+ (SCR_REG_SFBR (gpreg, SCR_LOAD, data))
+
+/*-----------------------------------------------------------
+**
+** Waiting for Disconnect or Reselect
+**
+**-----------------------------------------------------------
+**
+** JUMP [ | IFTRUE/IFFALSE ( ... ) ]
+** <<address>>
+**
+** JUMPR [ | IFTRUE/IFFALSE ( ... ) ]
+** <<distance>>
+**
+** CALL [ | IFTRUE/IFFALSE ( ... ) ]
+** <<address>>
+**
+** CALLR [ | IFTRUE/IFFALSE ( ... ) ]
+** <<distance>>
+**
+** RETURN [ | IFTRUE/IFFALSE ( ... ) ]
+** <<dummy>>
+**
+** INT [ | IFTRUE/IFFALSE ( ... ) ]
+** <<ident>>
+**
+** INT_FLY [ | IFTRUE/IFFALSE ( ... ) ]
+** <<ident>>
+**
+** Conditions:
+** WHEN (phase)
+** IF (phase)
+** CARRY
+** DATA (data, mask)
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_NO_OP 0x80000000
+#define SCR_JUMP 0x80080000
+#define SCR_JUMPR 0x80880000
+#define SCR_CALL 0x88080000
+#define SCR_CALLR 0x88880000
+#define SCR_RETURN 0x90080000
+#define SCR_INT 0x98080000
+#define SCR_INT_FLY 0x98180000
+
+#define IFFALSE(arg) (0x00080000 | (arg))
+#define IFTRUE(arg) (0x00000000 | (arg))
+
+#define WHEN(phase) (0x00030000 | (phase))
+#define IF(phase) (0x00020000 | (phase))
+
+#define DATA(D) (0x00040000 | ((D) & 0xff))
+#define MASK(D,M) (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff))
+
+#define CARRYSET (0x00200000)
+
+/*-----------------------------------------------------------
+**
+** SCSI constants.
+**
+**-----------------------------------------------------------
+*/
+
+/*
+** Messages
+*/
+#ifdef __OpenBSD__
+#include <scsi/scsi_message.h>
+
+#define M_COMPLETE MSG_CMDCOMPLETE
+#define M_EXTENDED MSG_EXTENDED
+#define M_SAVE_DP MSG_SAVEDATAPOINTER
+#define M_RESTORE_DP MSG_RESTOREPOINTERS
+#define M_DISCONNECT MSG_DISCONNECT
+#define M_ID_ERROR MSG_INITIATOR_DET_ERR
+#define M_ABORT MSG_ABORT
+#define M_REJECT MSG_MESSAGE_REJECT
+#define M_NOOP MSG_NOOP
+#define M_PARITY MSG_PARITY_ERROR
+#define M_LCOMPLETE MSG_LINK_CMD_COMPLETE
+#define M_FCOMPLETE MSG_LINK_CMD_COMPLETEF
+#define M_RESET MSG_BUS_DEV_RESET
+#define M_ABORT_TAG MSG_ABORT_TAG
+#define M_CLEAR_QUEUE MSG_CLEAR_QUEUE
+#define M_INIT_REC MSG_INIT_RECOVERY
+#define M_REL_REC MSG_REL_RECOVERY
+#define M_TERMINATE MSG_TERM_IO_PROC
+#define M_SIMPLE_TAG MSG_SIMPLE_Q_TAG
+#define M_HEAD_TAG MSG_HEAD_OF_Q_TAG
+#define M_ORDERED_TAG MSG_ORDERED_Q_TAG
+#define M_IGN_RESIDUE MSG_IGN_WIDE_RESIDUE
+#define M_IDENTIFY MSG_IDENTIFY(0, 0)
+
+/* #define M_X_MODIFY_DP (0x00) */ /* XXX what is this? */
+#define M_X_SYNC_REQ MSG_EXT_SDTR
+#define M_X_WIDE_REQ MSG_EXT_WDTR
+#else
+#define M_COMPLETE (0x00)
+#define M_EXTENDED (0x01)
+#define M_SAVE_DP (0x02)
+#define M_RESTORE_DP (0x03)
+#define M_DISCONNECT (0x04)
+#define M_ID_ERROR (0x05)
+#define M_ABORT (0x06)
+#define M_REJECT (0x07)
+#define M_NOOP (0x08)
+#define M_PARITY (0x09)
+#define M_LCOMPLETE (0x0a)
+#define M_FCOMPLETE (0x0b)
+#define M_RESET (0x0c)
+#define M_ABORT_TAG (0x0d)
+#define M_CLEAR_QUEUE (0x0e)
+#define M_INIT_REC (0x0f)
+#define M_REL_REC (0x10)
+#define M_TERMINATE (0x11)
+#define M_SIMPLE_TAG (0x20)
+#define M_HEAD_TAG (0x21)
+#define M_ORDERED_TAG (0x22)
+#define M_IGN_RESIDUE (0x23)
+#define M_IDENTIFY (0x80)
+
+#define M_X_MODIFY_DP (0x00)
+#define M_X_SYNC_REQ (0x01)
+#define M_X_WIDE_REQ (0x03)
+#endif
+
+
+/*
+** Status
+*/
+
+#define S_GOOD (0x00)
+#define S_CHECK_COND (0x02)
+#define S_COND_MET (0x04)
+#define S_BUSY (0x08)
+#define S_INT (0x10)
+#define S_INT_COND_MET (0x14)
+#define S_CONFLICT (0x18)
+#define S_TERMINATED (0x20)
+#define S_QUEUE_FULL (0x28)
+#define S_ILLEGAL (0xff)
+#define S_SENSE (0x80)
+
+/*
+** Bits defining chip features.
+** For now only some of them are used, since we explicitely
+** deal with PCI device id and revision id.
+*/
+#define FE_LED0 (1<<0)
+#define FE_WIDE (1<<1)
+#define FE_ULTRA (1<<2)
+#define FE_ULTRA2 (1<<3)
+#define FE_DBLR (1<<4)
+#define FE_QUAD (1<<5)
+#define FE_ERL (1<<6)
+#define FE_CLSE (1<<7)
+#define FE_WRIE (1<<8)
+#define FE_ERMP (1<<9)
+#define FE_BOF (1<<10)
+#define FE_DFS (1<<11)
+#define FE_PFEN (1<<12)
+#define FE_LDSTR (1<<13)
+#define FE_RAM (1<<14)
+#define FE_CLK80 (1<<15)
+#define FE_DIFF (1<<16)
+#define FE_BIOS (1<<17)
+#define FE_CACHE_SET (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
+#define FE_SCSI_SET (FE_WIDE|FE_ULTRA|FE_ULTRA2|FE_DBLR|FE_QUAD|F_CLK80)
+#define FE_SPECIAL_SET (FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM)
+
+#endif /*__NCR_REG_H__*/