? sys/arch/hp700/hardcopy.0
Index: sys/arch/hp700/gsc/harmony.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp700/gsc/harmony.c,v
retrieving revision 1.12
diff -u -u -r1.12 harmony.c
--- sys/arch/hp700/gsc/harmony.c	4 Jul 2008 11:18:02 -0000	1.12
+++ sys/arch/hp700/gsc/harmony.c	20 Sep 2008 09:17:10 -0000
@@ -130,7 +130,8 @@
 void harmony_start_cp(struct harmony_softc *);
 void harmony_tick_pb(void *);
 void harmony_tick_cp(void *);
-void harmony_try_more(struct harmony_softc *);
+void harmony_try_more(struct harmony_softc *, struct harmony_channel *,
+	int, int);
 
 #if NRND > 0
 void harmony_acc_tmo(void *);
@@ -367,15 +368,38 @@
 		WRITE_REG(sc, HARMONY_PNXTADD, nextaddr);
 		SYNC_REG(sc, HARMONY_PNXTADD, BUS_SPACE_BARRIER_WRITE);
 		c->c_lastaddr = nextaddr + togo;
-		harmony_try_more(sc);
+		harmony_try_more(sc, &sc->sc_playback,
+		    HARMONY_PCURADD, PCURADD_BUFMASK);
 	}
 
-	if (dstatus & DSTATUS_RN) {
-		c = &sc->sc_capture;
+	if (sc->sc_capturing && (dstatus & DSTATUS_RN)) {
+		struct harmony_dma *d;
+		bus_addr_t nextaddr;
+		bus_size_t togo;
+
 		r = 1;
-		harmony_start_cp(sc);
-		if (sc->sc_capturing && c->c_intr != NULL)
-			(*c->c_intr)(c->c_intrarg);
+		c = &sc->sc_capture;
+		d = c->c_current;
+		togo = c->c_segsz - c->c_cnt;
+		if (togo == 0) {
+			nextaddr = d->d_map->dm_segs[0].ds_addr;
+			c->c_cnt = togo = c->c_blksz;
+		} else {
+			nextaddr = c->c_lastaddr;
+			if (togo > c->c_blksz)
+				togo = c->c_blksz;
+			c->c_cnt += togo;
+		}
+
+		bus_dmamap_sync(sc->sc_dmat, d->d_map,
+		    nextaddr - d->d_map->dm_segs[0].ds_addr,
+		    c->c_blksz, BUS_DMASYNC_PREWRITE);
+
+		WRITE_REG(sc, HARMONY_RNXTADD, nextaddr);
+		SYNC_REG(sc, HARMONY_RNXTADD, BUS_SPACE_BARRIER_WRITE);
+		c->c_lastaddr = nextaddr + togo;
+		harmony_try_more(sc, &sc->sc_capture,
+		    HARMONY_RCURADD, RCURADD_BUFMASK);
 	}
 
 	if (READ_REG(sc, HARMONY_OV) & OV_OV) {
@@ -1315,17 +1339,16 @@
 }
 
 void
-harmony_try_more(struct harmony_softc *sc)
+harmony_try_more(struct harmony_softc *sc, struct harmony_channel *c,
+	int current_addr, int bufmask)
 {
-	struct harmony_channel *c;
 	struct harmony_dma *d;
 	uint32_t cur;
 	int i, nsegs;
 
-	c = &sc->sc_playback;
 	d = c->c_current;
-	cur = bus_space_read_4(sc->sc_bt, sc->sc_bh, HARMONY_PCURADD);
-	cur &= PCURADD_BUFMASK;
+	cur = bus_space_read_4(sc->sc_bt, sc->sc_bh, current_addr);
+	cur &= bufmask;
 	nsegs = 0;
 
 #ifdef DIAGNOSTIC
Index: sys/arch/hp700/gsc/harmonyreg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/hp700/gsc/harmonyreg.h,v
retrieving revision 1.2
diff -u -u -r1.2 harmonyreg.h
--- sys/arch/hp700/gsc/harmonyreg.h	11 Dec 2005 12:17:24 -0000	1.2
+++ sys/arch/hp700/gsc/harmonyreg.h	20 Sep 2008 09:17:10 -0000
@@ -128,7 +128,7 @@
 #define	PCURADD_BUFMASK		(~(HARMONY_BUFSIZE - 1))
 
 /* HARMONY_RCURADD */
-#define	PCURADD_BUFMASK		(~(HARMONY_BUFSIZE - 1))
+#define	RCURADD_BUFMASK		(~(HARMONY_BUFSIZE - 1))
 
 /* HARMONY_DSTATUS */
 #define	DSTATUS_IE		0x80000000	/* interrupt enable */
