Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/next68k/dev minor rework of dma driver
details: https://anonhg.NetBSD.org/src/rev/1af8576e058a
branches: trunk
changeset: 475882:1af8576e058a
user: dbj <dbj%NetBSD.org@localhost>
date: Sun Aug 29 05:56:26 1999 +0000
description:
minor rework of dma driver
now uses the DMACSR_READ bit and no longer keeps _nd_dmadir in softc
unified transfer cleanup code, now in routine next_dma_finish_xfer()
fixed bounds checking on registers after transfer.
removed checking for bus errors since the bit is always set on some nexts
(specifically, on mourning, a 25mhz 68040 mono slab)
fixed a couple of dma bugs involving chaining dma buffers.
diffstat:
sys/arch/next68k/dev/nextdma.c | 419 ++++++++++++++-----------------------
sys/arch/next68k/dev/nextdmavar.h | 4 +-
2 files changed, 166 insertions(+), 257 deletions(-)
diffs (truncated from 597 to 300 lines):
diff -r 549137e440b1 -r 1af8576e058a sys/arch/next68k/dev/nextdma.c
--- a/sys/arch/next68k/dev/nextdma.c Sun Aug 29 05:51:45 1999 +0000
+++ b/sys/arch/next68k/dev/nextdma.c Sun Aug 29 05:56:26 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nextdma.c,v 1.19 1999/08/28 09:19:05 dbj Exp $ */
+/* $NetBSD: nextdma.c,v 1.20 1999/08/29 05:56:26 dbj Exp $ */
/*
* Copyright (c) 1998 Darrin B. Jewell
* All rights reserved.
@@ -71,6 +71,7 @@
void next_dma_setup_cont_regs __P((struct nextdma_config *));
void next_dma_setup_curr_regs __P((struct nextdma_config *));
+void next_dma_finish_xfer __P((struct nextdma_config *));
void
nextdma_config(nd)
@@ -115,7 +116,6 @@
DPRINTF(("DMA init ipl (%ld) intr(0x%b)\n",
NEXT_I_IPL(nd->nd_intr), NEXT_I_BIT(nd->nd_intr),NEXT_INTR_BITS));
- /* @@@ should probably check and free these maps */
nd->_nd_map = NULL;
nd->_nd_idx = 0;
nd->_nd_map_cont = NULL;
@@ -123,26 +123,29 @@
bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_CSR, 0);
bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_CSR,
- DMACSR_INITBUF | DMACSR_CLRCOMPLETE | DMACSR_RESET);
+ DMACSR_RESET | DMACSR_INITBUF);
next_dma_setup_curr_regs(nd);
next_dma_setup_cont_regs(nd);
-#if 0 && defined(DIAGNOSTIC)
- /* Today, my computer (mourning) appears to fail this test.
- * yesterday, another NeXT (milo) didn't have this problem
- * Darrin B. Jewell <jewell%mit.edu@localhost> Mon May 25 07:53:05 1998
- */
+#if defined(DIAGNOSTIC)
{
u_long state;
state = bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_CSR);
- state = bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_CSR);
+
+#if 1
+ /* mourning (a 25Mhz 68040 mono slab) appears to set BUSEXC
+ * milo (a 25Mhz 68040 mono cube) didn't have this problem
+ * Darrin B. Jewell <jewell%mit.edu@localhost> Mon May 25 07:53:05 1998
+ */
+ state &= (DMACSR_COMPLETE | DMACSR_SUPDATE | DMACSR_ENABLE);
+#else
state &= (DMACSR_BUSEXC | DMACSR_COMPLETE |
DMACSR_SUPDATE | DMACSR_ENABLE);
-
+#endif
if (state) {
next_dma_print(nd);
- panic("DMA did not reset\n");
+ panic("DMA did not reset");
}
}
#endif
@@ -162,6 +165,8 @@
if (nextdma_debug) next_dma_print(nd);
#endif
+ /* @@@ clean up dma maps */
+
nextdma_init(nd);
splx(s);
}
@@ -179,22 +184,6 @@
DPRINTF(("DMA next_dma_rotate()\n"));
-#ifdef DIAGNOSTIC
- if (nd->_nd_map &&
- nd->_nd_map->dm_segs[nd->_nd_idx].ds_xfer_len == 0x1234beef) {
- next_dma_print(nd);
- panic("DMA didn't set xfer length of segment");
- }
-#endif
-
- /* If we've reached the end of the current map, then inform
- * that we've completed that map.
- */
- if (nd->_nd_map && ((nd->_nd_idx+1) == nd->_nd_map->dm_nsegs)) {
- if (nd->nd_completed_cb)
- (*nd->nd_completed_cb)(nd->_nd_map, nd->nd_cb_arg);
- }
-
/* Rotate the continue map into the current map */
nd->_nd_map = nd->_nd_map_cont;
nd->_nd_idx = nd->_nd_idx_cont;
@@ -236,95 +225,91 @@
next_dma_setup_cont_regs(nd)
struct nextdma_config *nd;
{
+ bus_addr_t dd_start;
+ bus_addr_t dd_stop;
+ bus_addr_t dd_saved_start;
+ bus_addr_t dd_saved_stop;
+
DPRINTF(("DMA next_dma_setup_regs()\n"));
if (nd->_nd_map_cont) {
+ dd_start = nd->_nd_map_cont->dm_segs[nd->_nd_idx_cont].ds_addr;
+ dd_stop = (nd->_nd_map_cont->dm_segs[nd->_nd_idx_cont].ds_addr +
+ nd->_nd_map_cont->dm_segs[nd->_nd_idx_cont].ds_len);
if (nd->nd_intr == NEXT_I_ENETX_DMA) {
- /* Ethernet transmit needs secret magic */
-
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_START,
- nd->_nd_map_cont->dm_segs[nd->_nd_idx_cont].ds_addr);
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_STOP,
- ((nd->_nd_map_cont->dm_segs[nd->_nd_idx_cont].ds_addr +
- nd->_nd_map_cont->dm_segs[nd->_nd_idx_cont].ds_len)
- + 0x0) | 0x80000000);
-
+ dd_stop |= 0x80000000; /* Ethernet transmit needs secret magic */
}
- else {
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_START,
- nd->_nd_map_cont->dm_segs[nd->_nd_idx_cont].ds_addr);
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_STOP,
- nd->_nd_map_cont->dm_segs[nd->_nd_idx_cont].ds_addr +
- nd->_nd_map_cont->dm_segs[nd->_nd_idx_cont].ds_len);
- }
-
} else {
-
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_START, 0xdeadbeef);
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_STOP, 0xdeadbeef);
+ dd_start = 0xdeadbeef;
+ dd_stop = 0xdeadbeef;
}
-#if 1 /* 0xfeedbeef in these registers leads to instability. it will
- * panic after a short while with 0xfeedbeef in the DD_START and DD_STOP
- * registers. I suspect that an unexpected hardware restart
- * is cycling the bogus values into the active registers. Until
- * that is understood, we seed these with the same as DD_START and DD_STOP
- */
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_START,
- bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_START));
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_STOP,
- bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_STOP));
-#else
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_START, 0xfeedbeef);
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_STOP, 0xfeedbeef);
+ dd_saved_start = dd_start;
+ dd_saved_stop = dd_stop;
+
+ bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_START, dd_start);
+ bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_STOP, dd_stop);
+ bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_START, dd_saved_start);
+ bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_STOP, dd_saved_stop);
+
+#ifdef DIAGNOSTIC
+ if ((bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_START) != dd_start) ||
+ (bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_STOP) != dd_stop) ||
+ (bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_START) != dd_saved_start) ||
+ (bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_STOP) != dd_saved_stop)) {
+ next_dma_print(nd);
+ panic("DMA failure writing to continue regs");
+ }
#endif
-
}
void
next_dma_setup_curr_regs(nd)
struct nextdma_config *nd;
{
+ bus_addr_t dd_next;
+ bus_addr_t dd_limit;
+ bus_addr_t dd_saved_next;
+ bus_addr_t dd_saved_limit;
+
DPRINTF(("DMA next_dma_setup_curr_regs()\n"));
if (nd->_nd_map) {
-
+ dd_next = nd->_nd_map->dm_segs[nd->_nd_idx].ds_addr;
+ dd_limit = (nd->_nd_map->dm_segs[nd->_nd_idx].ds_addr +
+ nd->_nd_map->dm_segs[nd->_nd_idx].ds_len);
if (nd->nd_intr == NEXT_I_ENETX_DMA) {
- /* Ethernet transmit needs secret magic */
-
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_NEXT_INITBUF,
- nd->_nd_map->dm_segs[nd->_nd_idx].ds_addr);
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_LIMIT,
- ((nd->_nd_map->dm_segs[nd->_nd_idx].ds_addr +
- nd->_nd_map->dm_segs[nd->_nd_idx].ds_len)
- + 0x0) | 0x80000000);
-
+ dd_limit |= 0x80000000; /* Ethernet transmit needs secret magic */
}
- else {
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_NEXT_INITBUF,
- nd->_nd_map->dm_segs[nd->_nd_idx].ds_addr);
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_LIMIT,
- nd->_nd_map->dm_segs[nd->_nd_idx].ds_addr +
- nd->_nd_map->dm_segs[nd->_nd_idx].ds_len);
- }
-
} else {
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_NEXT_INITBUF,0xdeadbeef);
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_LIMIT, 0xdeadbeef);
+ dd_next = 0xdeadbeef;
+ dd_limit = 0xdeadbeef;
}
-#if 1 /* See comment in next_dma_setup_cont_regs() above */
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_NEXT,
- bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_NEXT_INITBUF));
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_LIMIT,
- bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_LIMIT));
-#else
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_NEXT, 0xfeedbeef);
- bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_LIMIT, 0xfeedbeef);
+ dd_saved_next = dd_next;
+ dd_saved_limit = dd_limit;
+
+ if (nd->nd_intr == NEXT_I_ENETX_DMA) {
+ bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_NEXT_INITBUF, dd_next);
+ } else {
+ bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_NEXT, dd_next);
+ }
+ bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_LIMIT, dd_limit);
+ bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_NEXT, dd_saved_next);
+ bus_space_write_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_LIMIT, dd_saved_limit);
+
+#ifdef DIAGNOSTIC
+ if ((bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_NEXT_INITBUF) != dd_next) ||
+ (bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_NEXT) != dd_next) ||
+ (bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_LIMIT) != dd_limit) ||
+ (bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_NEXT) != dd_saved_next) ||
+ (bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_LIMIT) != dd_saved_limit)) {
+ next_dma_print(nd);
+ panic("DMA failure writing to current regs");
+ }
#endif
-
}
@@ -359,9 +344,12 @@
dd_saved_start = bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_START);
dd_saved_stop = bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_STOP);
- /* NDMAP is Next DMA Print (really!) */
+ printf("NDMAP: *intrstat = 0x%b\n",
+ (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),NEXT_INTR_BITS);
+ printf("NDMAP: *intrmask = 0x%b\n",
+ (*(volatile u_long *)IIOV(NEXT_P_INTRMASK)),NEXT_INTR_BITS);
- printf("NDMAP: nd->_nd_dmadir = 0x%08x\n",nd->_nd_dmadir);
+ /* NDMAP is Next DMA Print (really!) */
if (nd->_nd_map) {
printf("NDMAP: nd->_nd_map->dm_mapsize = %d\n",
@@ -408,6 +396,47 @@
}
/****************************************************************/
+void
+next_dma_finish_xfer(nd)
+ struct nextdma_config *nd;
+{
+ bus_addr_t onext;
+ bus_addr_t olimit;
+ bus_addr_t slimit;
+
+ onext = nd->_nd_map->dm_segs[nd->_nd_idx].ds_addr;
+ olimit = onext + nd->_nd_map->dm_segs[nd->_nd_idx].ds_len;
+
+ if ((nd->_nd_map_cont == NULL) && (nd->_nd_idx+1 == nd->_nd_map->dm_nsegs)) {
+ slimit = bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_LIMIT);
+ } else {
+ slimit = bus_space_read_4(nd->nd_bst, nd->nd_bsh, DD_SAVED_LIMIT);
+ }
+
+ if (nd->nd_intr == NEXT_I_ENETX_DMA) {
+ slimit &= ~0x80000000;
+ }
+
+#ifdef DIAGNOSTIC
+ if ((slimit < onext) || (slimit > olimit)) {
+ next_dma_print(nd);
+ panic("DMA: Unexpected registers in finish_xfer\n");
+ }
+#endif
+
+ nd->_nd_map->dm_segs[nd->_nd_idx].ds_xfer_len = slimit-onext;
+
Home |
Main Index |
Thread Index |
Old Index