summaryrefslogtreecommitdiff
path: root/sys/arch/sparc/dev
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2005-03-02 16:42:38 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2005-03-02 16:42:38 +0000
commit75699d05e12889fd103ff022333d521b76b4eebd (patch)
treef5fac7dabfe42ee6f627be04b084ad71ea4351f6 /sys/arch/sparc/dev
parent835ad1539d3707443bfadd1763cc0383eab238e4 (diff)
Support for SUNW,fas SCSI, currently restricted to the lower 8 targets due
to MI esp code limitations. ok deraadt@
Diffstat (limited to 'sys/arch/sparc/dev')
-rw-r--r--sys/arch/sparc/dev/dma.c137
-rw-r--r--sys/arch/sparc/dev/dmavar.h6
-rw-r--r--sys/arch/sparc/dev/esp.c234
3 files changed, 290 insertions, 87 deletions
diff --git a/sys/arch/sparc/dev/dma.c b/sys/arch/sparc/dev/dma.c
index 0ecfa849131..18b45f116ef 100644
--- a/sys/arch/sparc/dev/dma.c
+++ b/sys/arch/sparc/dev/dma.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dma.c,v 1.20 2005/02/27 22:01:03 miod Exp $ */
+/* $OpenBSD: dma.c,v 1.21 2005/03/02 16:42:37 miod Exp $ */
/* $NetBSD: dma.c,v 1.46 1997/08/27 11:24:16 bouyer Exp $ */
/*
@@ -131,6 +131,7 @@ dmaattach(parent, self, aux)
{
struct confargs *ca = aux;
struct dma_softc *sc = (void *)self;
+ int devnode;
#if defined(SUN4C) || defined(SUN4M)
int node;
struct confargs oca;
@@ -142,6 +143,7 @@ dmaattach(parent, self, aux)
mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
sc->sc_regs = (struct dma_regs *) ca->ca_ra.ra_vaddr;
+ devnode = ca->ca_ra.ra_node;
/*
* If we're a ledma, check to see what cable type is currently
@@ -151,8 +153,7 @@ dmaattach(parent, self, aux)
* can change it via a "link0" option to ifconfig.
*/
if (strcmp(ca->ca_ra.ra_name, "ledma") == 0) {
- char *cabletype = getpropstring(ca->ca_ra.ra_node,
- "cable-selection");
+ char *cabletype = getpropstring(devnode, "cable-selection");
if (strcmp(cabletype, "tpe") == 0) {
sc->sc_regs->csr |= E_TP_AUI;
} else if (strcmp(cabletype, "aui") == 0) {
@@ -174,7 +175,7 @@ dmaattach(parent, self, aux)
if (sbusburst == 0)
sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
- sc->sc_burst = getpropint(ca->ca_ra.ra_node,"burst-sizes", -1);
+ sc->sc_burst = getpropint(devnode, "burst-sizes", -1);
if (sc->sc_burst == -1)
/* take SBus burst sizes */
sc->sc_burst = sbusburst;
@@ -201,25 +202,17 @@ dmaattach(parent, self, aux)
case DMAREV_2:
printf("2");
break;
+ case DMAREV_HME:
+ printf("fas");
+ break;
default:
printf("unknown (0x%x)", sc->sc_rev);
}
printf("\n");
/* indirect functions */
- if (sc->sc_dev.dv_cfdata->cf_attach == &dma_ca) {
- sc->reset = espdma_reset;
- sc->intr = espdmaintr;
- } else {
- sc->reset = ledma_reset;
- sc->intr = ledmaintr;
- }
- sc->enintr = dma_enintr;
- sc->isintr = dma_isintr;
- sc->setup = dma_setup;
- sc->go = dma_go;
+ dma_setuphandlers(sc);
- sc->sc_node = ca->ca_ra.ra_node;
if (CPU_ISSUN4)
goto espsearch;
@@ -237,7 +230,7 @@ dmaattach(parent, self, aux)
oca.ca_ra.ra_bp = NULL;
/* search through children */
- node = firstchild(sc->sc_node);
+ node = firstchild(devnode);
if (node != 0) do {
name = getpropstring(node, "name");
if (!romprop(&oca.ca_ra, name, node))
@@ -272,6 +265,23 @@ espsearch:
}
}
+void
+dma_setuphandlers(struct dma_softc *sc)
+{
+ if (sc->sc_dev.dv_cfdata == NULL || /* happens on SUNW,fas */
+ sc->sc_dev.dv_cfdata->cf_attach == &dma_ca) {
+ sc->reset = espdma_reset;
+ sc->intr = espdmaintr;
+ } else {
+ sc->reset = ledma_reset;
+ sc->intr = ledmaintr;
+ }
+ sc->enintr = dma_enintr;
+ sc->isintr = dma_isintr;
+ sc->setup = dma_setup;
+ sc->go = dma_go;
+}
+
#define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) { \
int count = 500000; \
while ((COND) && --count > 0) DELAY(1); \
@@ -293,14 +303,16 @@ espsearch:
* other revs: D_ESC_R_PEND bit reads as 0 \
*/ \
DMAWAIT(sc, sc->sc_regs->csr & D_ESC_R_PEND, "R_PEND", dontpanic);\
- /* \
- * Select drain bit based on revision \
- * also clears errors and D_TC flag \
- */ \
- if (sc->sc_rev == DMAREV_1 || sc->sc_rev == DMAREV_0) \
- DMACSR(sc) |= D_ESC_DRAIN; \
- else \
- DMACSR(sc) |= D_INVALIDATE; \
+ if (sc->sc_rev != DMAREV_HME) { \
+ /* \
+ * Select drain bit based on revision \
+ * also clears errors and D_TC flag \
+ */ \
+ if (sc->sc_rev == DMAREV_1 || sc->sc_rev == DMAREV_0) \
+ DMACSR(sc) |= D_ESC_DRAIN; \
+ else \
+ DMACSR(sc) |= D_INVALIDATE; \
+ } \
/* \
* Wait for draining to finish \
* rev0 & rev1 call this PACKCNT \
@@ -318,8 +330,8 @@ espsearch:
*/ \
DMAWAIT(sc, sc->sc_regs->csr & D_ESC_R_PEND, "R_PEND", dontpanic);\
csr = DMACSR(sc); \
- csr &= ~(D_WRITE|D_EN_DMA); \
- csr |= D_INVALIDATE; \
+ csr &= ~(D_WRITE|D_EN_DMA); /* no-ops on ENET */ \
+ csr |= D_INVALIDATE; /* XXX FAS ? */ \
DMACSR(sc) = csr; \
} while(0)
@@ -328,36 +340,59 @@ dma_reset(sc, isledma)
struct dma_softc *sc;
int isledma;
{
+ int csr;
+
DMA_FLUSH(sc, 1);
- DMACSR(sc) |= D_RESET; /* reset DMA */
- DELAY(200); /* what should this be ? */
+ csr = DMACSR(sc);
+
+ if (sc->sc_rev == DMAREV_HME)
+ DMACSR(sc) = csr | D_HW_RESET_FAS366;
+
+ csr |= D_RESET; /* reset DMA */
+ DMACSR(sc) = csr;
+ DELAY(200); /* > 10 Sbus clocks(?) */
+
/*DMAWAIT1(sc); why was this here? */
DMACSR(sc) &= ~D_RESET; /* de-assert reset line */
- DMACSR(sc) |= D_INT_EN; /* enable interrupts */
- if (sc->sc_rev > DMAREV_1 && isledma == 0)
- DMACSR(sc) |= D_FASTER;
+ DELAY(5);
+
+ csr = DMACSR(sc);
+ csr |= D_INT_EN; /* enable interrupts */
+ if (sc->sc_rev > DMAREV_1 && isledma == 0) {
+ if (sc->sc_rev == DMAREV_HME)
+ csr |= D_TWO_CYCLE;
+ else
+ csr |= D_FASTER;
+ }
switch (sc->sc_rev) {
+ case DMAREV_HME:
case DMAREV_2:
- sc->sc_regs->csr &= ~L64854_BURST_SIZE; /* must clear first */
+ csr &= ~L64854_BURST_SIZE; /* must clear first */
if (sc->sc_burst & SBUS_BURST_32) {
- DMACSR(sc) |= L64854_BURST_32;
+ csr |= L64854_BURST_32;
} else if (sc->sc_burst & SBUS_BURST_16) {
- DMACSR(sc) |= L64854_BURST_16;
+ csr |= L64854_BURST_16;
} else {
- DMACSR(sc) |= L64854_BURST_0;
+ csr |= L64854_BURST_0;
}
break;
case DMAREV_ESC:
- DMACSR(sc) |= D_ESC_AUTODRAIN; /* Auto-drain */
+ csr |= D_ESC_AUTODRAIN; /* Auto-drain */
if (sc->sc_burst & SBUS_BURST_32) {
- DMACSR(sc) &= ~0x800;
+ csr &= ~D_ESC_BURST;
} else
- DMACSR(sc) |= 0x800;
+ csr |= D_ESC_BURST;
break;
default:
break;
}
+ DMACSR(sc) = csr;
+
+ if (sc->sc_rev == DMAREV_HME) {
+ DMADDR(sc) = 0;
+ sc->sc_dmactl = csr;
+ }
sc->sc_active = 0; /* and of course we aren't */
}
@@ -445,6 +480,15 @@ dma_setup(sc, addr, len, datain, dmasize)
NCR_DMA(("dma_setup: dmasize = %d\n", sc->sc_dmasize));
+ /*
+ * XXX what length?
+ */
+ if (sc->sc_rev == DMAREV_HME) {
+ DMACSR(sc) = sc->sc_dmactl | L64854_RESET;
+ DMACSR(sc) = sc->sc_dmactl;
+ DMACNT(sc) = *dmasize;
+ }
+
/* Program the DMA address */
if (CPU_ISSUN4M && sc->sc_dmasize) {
/*
@@ -474,6 +518,11 @@ dma_setup(sc, addr, len, datain, dmasize)
else
csr &= ~D_WRITE;
csr |= D_INT_EN;
+
+ if (sc->sc_rev == DMAREV_HME) {
+ csr |= (D_DSBL_SCSI_DRN | D_EN_DMA);
+ }
+
DMACSR(sc) = csr;
return 0;
@@ -503,17 +552,19 @@ espdmaintr(sc)
struct ncr53c9x_softc *nsc = &sc->sc_esp->sc_ncr53c9x;
int trans, resid;
u_long csr;
+
csr = DMACSR(sc);
NCR_DMA(("%s: intr: addr %p, csr %b\n", sc->sc_dev.dv_xname,
DMADDR(sc), csr, DDMACSR_BITS));
- if (csr & D_ERR_PEND) {
- DMACSR(sc) &= ~D_EN_DMA; /* Stop DMA */
- DMACSR(sc) |= D_INVALIDATE;
+ if (csr & (D_ERR_PEND|D_SLAVE_ERR)) {
printf("%s: error: csr=%b\n", sc->sc_dev.dv_xname,
csr, DDMACSR_BITS);
- return -1;
+ DMACSR(sc) &= ~D_EN_DMA; /* Stop DMA */
+ /* Invalidate the queue; SLAVE_ERR bit is write-to-clear */
+ DMACSR(sc) |= D_INVALIDATE|D_SLAVE_ERR;
+ return (-1);
}
/* This is an "assertion" :) */
diff --git a/sys/arch/sparc/dev/dmavar.h b/sys/arch/sparc/dev/dmavar.h
index 622e2297457..b86cf79d1c3 100644
--- a/sys/arch/sparc/dev/dmavar.h
+++ b/sys/arch/sparc/dev/dmavar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dmavar.h,v 1.5 2003/06/05 12:27:02 deraadt Exp $ */
+/* $OpenBSD: dmavar.h,v 1.6 2005/03/02 16:42:37 miod Exp $ */
/* $NetBSD: dmavar.h,v 1.11 1996/11/27 21:49:53 pk Exp $ */
/*
@@ -32,7 +32,6 @@ struct dma_softc {
struct dma_regs *sc_regs; /* the registers */
int sc_active; /* DMA active ? */
u_int sc_rev; /* revision */
- int sc_node; /* PROM node ID */
int sc_burst; /* DVMA burst size in effect */
caddr_t sc_dvmakaddr; /* DVMA cookies */
caddr_t sc_dvmaaddr; /* */
@@ -45,6 +44,7 @@ struct dma_softc {
int (*intr)(struct dma_softc *); /* interrupt ! */
int (*setup)(struct dma_softc *, caddr_t *, size_t *, int, size_t *);
void (*go)(struct dma_softc *);
+ u_int sc_dmactl;
};
#define DMACSR(sc) (sc->sc_regs->csr)
@@ -59,3 +59,5 @@ struct dma_softc {
#define DMA_ISACTIVE(r) ((r)->sc_active)
#define DMA_SETUP(a, b, c, d, e) (((a)->setup)(a, b, c, d, e))
#define DMA_GO(r) (((r)->go)(r))
+
+void dma_setuphandlers(struct dma_softc *);
diff --git a/sys/arch/sparc/dev/esp.c b/sys/arch/sparc/dev/esp.c
index 245e94d8a6b..520b3e90e43 100644
--- a/sys/arch/sparc/dev/esp.c
+++ b/sys/arch/sparc/dev/esp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: esp.c,v 1.22 2004/09/29 07:35:11 miod Exp $ */
+/* $OpenBSD: esp.c,v 1.23 2005/03/02 16:42:37 miod Exp $ */
/* $NetBSD: esp.c,v 1.69 1997/08/27 11:24:18 bouyer Exp $ */
/*
@@ -107,6 +107,7 @@
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/queue.h>
+#include <sys/malloc.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
@@ -150,6 +151,8 @@ struct scsi_device esp_dev = {
*/
u_char esp_read_reg(struct ncr53c9x_softc *, int);
void esp_write_reg(struct ncr53c9x_softc *, int, u_char);
+u_char esp_rdreg1(struct ncr53c9x_softc *, int);
+void esp_wrreg1(struct ncr53c9x_softc *, int, u_char);
int esp_dma_isintr(struct ncr53c9x_softc *);
void esp_dma_reset(struct ncr53c9x_softc *);
int esp_dma_intr(struct ncr53c9x_softc *);
@@ -172,6 +175,21 @@ struct ncr53c9x_glue esp_glue = {
NULL, /* gl_clear_latched_intr */
};
+#if defined(SUN4C) || defined(SUN4M)
+struct ncr53c9x_glue esp_glue1 = {
+ esp_rdreg1,
+ esp_wrreg1,
+ esp_dma_isintr,
+ esp_dma_reset,
+ esp_dma_intr,
+ esp_dma_setup,
+ esp_dma_go,
+ esp_dma_stop,
+ esp_dma_isactive,
+ NULL, /* gl_clear_latched_intr */
+};
+#endif
+
int
espmatch(parent, vcf, aux)
struct device *parent;
@@ -181,6 +199,14 @@ espmatch(parent, vcf, aux)
register struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
+#if defined(SUN4C) || defined(SUN4M)
+ if (ca->ca_bustype == BUS_SBUS) {
+ if (strcmp("SUNW,fas", ra->ra_name) == 0 ||
+ strcmp("ptscII", ra->ra_name) == 0)
+ return (1);
+ }
+#endif
+
if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
return (0);
#if defined(SUN4C) || defined(SUN4M)
@@ -206,16 +232,12 @@ espattach(parent, self, aux)
struct esp_softc *esc = (void *)self;
struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
struct bootpath *bp;
- int dmachild = strncmp(parent->dv_xname, "dma", 3) == 0;
+ int dmachild;
+ unsigned int uid = 0;
/*
- * Set up glue for MI code early; we use some of it here.
- */
- sc->sc_glue = &esp_glue;
-
- /*
- * Make sure things are sane. I don't know if this is ever
- * necessary, but it seem to be in all of Torek's code.
+ * If no interrupts properties, bail out: this might happen
+ * on the Sparc X terminal.
*/
if (ca->ca_ra.ra_nintr != 1) {
printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
@@ -225,17 +247,6 @@ espattach(parent, self, aux)
esc->sc_pri = ca->ca_ra.ra_intr[0].int_pri;
printf(" pri %d", esc->sc_pri);
- /*
- * Map my registers in, if they aren't already in virtual
- * address space.
- */
- if (ca->ca_ra.ra_vaddr)
- esc->sc_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
- else {
- esc->sc_reg = (volatile u_char *)
- mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
- }
-
/* Other settings */
esc->sc_node = ca->ca_ra.ra_node;
if (ca->ca_bustype == BUS_SBUS) {
@@ -252,34 +263,142 @@ espattach(parent, self, aux)
/* gimme MHz */
sc->sc_freq /= 1000000;
- if (dmachild) {
- esc->sc_dma = (struct dma_softc *)parent;
- esc->sc_dma->sc_esp = esc;
- } else {
+#if defined(SUN4C) || defined(SUN4M)
+ if (ca->ca_bustype == BUS_SBUS &&
+ strcmp("SUNW,fas", ca->ca_ra.ra_name) == 0) {
+ struct dma_softc *dsc;
+
/*
- * find the DMA by poking around the dma device structures
- *
- * What happens here is that if the dma driver has not been
- * configured, then this returns a NULL pointer. Then when the
- * dma actually gets configured, it does the opposing test, and
- * if the sc->sc_esp field in it's softc is NULL, then tries to
- * find the matching esp driver.
+ * fas has 2 register spaces: DMA (lsi64854) and SCSI core
+ * (ncr53c9x).
*/
- esc->sc_dma = (struct dma_softc *)
- getdevunit("dma", sc->sc_dev.dv_unit);
+ if (ca->ca_ra.ra_nreg != 2) {
+ printf(": expected 2 register spaces, found %d\n",
+ ca->ca_ra.ra_nreg);
+ return;
+ }
/*
- * and a back pointer to us, for DMA
+ * Allocate a softc for the DMA companion, which will not
+ * get a regular attachment.
*/
- if (esc->sc_dma)
- esc->sc_dma->sc_esp = esc;
+ dsc = malloc(sizeof(struct dma_softc), M_DEVBUF, M_NOWAIT);
+ if (dsc == NULL) {
+ printf(": could not allocate dma softc\n");
+ return;
+ }
+ bzero(dsc, sizeof(struct dma_softc));
+ strlcpy(dsc->sc_dev.dv_xname, sc->sc_dev.dv_xname,
+ sizeof(dsc->sc_dev.dv_xname));
+ esc->sc_dma = dsc;
+
+ /*
+ * Map DMA registers
+ */
+ dsc->sc_regs = (struct dma_regs *)mapiodev(&ca->ca_ra.ra_reg[0],
+ 0, ca->ca_ra.ra_reg[0].rr_len);
+ if (dsc->sc_regs == NULL) {
+ printf(": could not map DMA registers\n");
+ return;
+ }
+ dsc->sc_rev = dsc->sc_regs->csr & D_DEV_ID;
+ dsc->sc_esp = esc;
+
+#ifdef SUN4M
+ /*
+ * Get transfer burst size from PROM and plug it into the
+ * controller registers. This is needed on the Sun4m; do
+ * others need it too?
+ */
+ if (CPU_ISSUN4M) {
+ int sbusburst;
+
+ sbusburst = ((struct sbus_softc *)parent)->sc_burst;
+ if (sbusburst == 0)
+ sbusburst = SBUS_BURST_32 - 1; /* 1 -> 16 */
+
+ dsc->sc_burst =
+ getpropint(ca->ca_ra.ra_node, "burst-sizes", -1);
+ if (dsc->sc_burst == -1)
+ /* take SBus burst sizes */
+ dsc->sc_burst = sbusburst;
+
+ /* Clamp at parent's burst sizes */
+ dsc->sc_burst &= sbusburst;
+ }
+#endif /* SUN4M */
+
+ /* indirect functions */
+ dma_setuphandlers(dsc);
+
+ /*
+ * Map SCSI core registers
+ */
+ esc->sc_reg = (volatile u_char *)mapiodev(&ca->ca_ra.ra_reg[1],
+ 0, ca->ca_ra.ra_reg[1].rr_len);
+ if (esc->sc_reg == NULL) {
+ printf(": could not map SCSI core registers\n");
+ return;
+ }
+
+ dmachild = 0;
+ } else
+#endif
+ {
+ /*
+ * Map my registers in, if they aren't already in virtual
+ * address space.
+ */
+ if (ca->ca_ra.ra_vaddr)
+ esc->sc_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
else {
- printf("\n");
- panic("espattach: no dma found");
+ esc->sc_reg = (volatile u_char *)
+ mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
+ }
+
+ dmachild = strncmp(parent->dv_xname, "dma", 3) == 0;
+ if (dmachild) {
+ esc->sc_dma = (struct dma_softc *)parent;
+ esc->sc_dma->sc_esp = esc;
+ } else {
+ /*
+ * Find the DMA by poking around the DMA device
+ * structures.
+ *
+ * What happens here is that if the DMA driver has
+ * not been configured, then this returns a NULL
+ * pointer. Then when the DMA actually gets configured,
+ * it does the opposite test, and if the sc->sc_esp
+ * field in its softc is NULL, then tries to find the
+ * matching esp driver.
+ */
+ esc->sc_dma = (struct dma_softc *)
+ getdevunit("dma", sc->sc_dev.dv_unit);
+
+ /*
+ * ...and a back pointer to us, for DMA.
+ */
+ if (esc->sc_dma)
+ esc->sc_dma->sc_esp = esc;
+ else {
+ printf("\n");
+ panic("espattach: no dma found");
+ }
}
}
/*
+ * Set up glue for MI code.
+ */
+#if defined(SUN4C) || defined(SUN4M)
+ if (ca->ca_bustype == BUS_SBUS &&
+ strcmp("ptscII", ca->ca_ra.ra_name) == 0) {
+ sc->sc_glue = &esp_glue1;
+ } else
+#endif
+ sc->sc_glue = &esp_glue;
+
+ /*
* XXX More of this should be in ncr53c9x_attach(), but
* XXX should we really poke around the chip that much in
* XXX the MI code? Think about this more...
@@ -314,6 +433,11 @@ espattach(parent, self, aux)
sc->sc_cfg3 = 0;
NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
sc->sc_rev = NCR_VARIANT_ESP200;
+
+ /* XXX spec says it's valid after power up or chip reset */
+ uid = NCR_READ_REG(sc, NCR_UID);
+ if (((uid & 0xf8) >> 3) == 0x0a) /* XXX */
+ sc->sc_rev = NCR_VARIANT_FAS366;
}
}
@@ -352,6 +476,7 @@ espattach(parent, self, aux)
break;
case NCR_VARIANT_ESP200:
+ case NCR_VARIANT_FAS366:
sc->sc_maxxfer = 16 * 1024 * 1024;
/* XXX - do actually set FAST* bits */
break;
@@ -368,7 +493,7 @@ espattach(parent, self, aux)
}
#endif /* SUN4C || SUN4M */
- /* and the interuppts */
+ /* and the interrupts */
esc->sc_ih.ih_fun = (void *) ncr53c9x_intr;
esc->sc_ih.ih_arg = sc;
intr_establish(esc->sc_pri, &esc->sc_ih, IPL_BIO, self->dv_xname);
@@ -392,12 +517,13 @@ espattach(parent, self, aux)
break;
}
+ /* Turn on target selection using the `dma' method */
+ if (sc->sc_rev != NCR_VARIANT_FAS366)
+ sc->sc_features |= NCR_F_DMASELECT;
+
/* Do the common parts of attachment. */
ncr53c9x_attach(sc, &esp_switch, &esp_dev);
- /* Turn on target selection using the `dma' method */
- sc->sc_features |= NCR_F_DMASELECT;
-
bootpath_store(1, NULL);
}
@@ -427,6 +553,30 @@ esp_write_reg(sc, reg, val)
esc->sc_reg[reg * 4] = v;
}
+#if defined(SUN4C) || defined(SUN4M)
+u_char
+esp_rdreg1(sc, reg)
+ struct ncr53c9x_softc *sc;
+ int reg;
+{
+ struct esp_softc *esc = (struct esp_softc *)sc;
+
+ return (esc->sc_reg[reg]);
+}
+
+void
+esp_wrreg1(sc, reg, val)
+ struct ncr53c9x_softc *sc;
+ int reg;
+ u_char val;
+{
+ struct esp_softc *esc = (struct esp_softc *)sc;
+ u_char v = val;
+
+ esc->sc_reg[reg] = v;
+}
+#endif
+
int
esp_dma_isintr(sc)
struct ncr53c9x_softc *sc;