? 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 */