PERFORCE change 108436 for review
Warner Losh
imp at FreeBSD.org
Wed Oct 25 14:02:34 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=108436
Change 108436 by imp at imp_lighthouse on 2006/10/25 21:02:14
Use the busdma callback mechanism correctly.
o flush cache after I'm sure that the uio is loaded.
o do all hackware frobbing inside the callback
o DO NOT ASSUME that the callback has happened after load_uio
has returned.
o protect more with the sc_mtx mutex.
o handle EINPROGRESS gracefully
Affected files ...
.. //depot/projects/arm/src/sys/arm/at91/at91_ssc.c#13 edit
Differences ...
==== //depot/projects/arm/src/sys/arm/at91/at91_ssc.c#13 (text+ko) ====
@@ -144,7 +144,7 @@
*/
err = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT,
BUS_SPACE_MAXADDR, NULL, NULL, 2048, 1, 2048, BUS_DMA_ALLOCNOW,
- NULL, NULL, &sc->tag);
+ busdma_lock_mutex, &sc->sc_mtx, &sc->tag);
if (err != 0)
goto out;
err = bus_dmamap_create(sc->tag, 0, &sc->tx_map);
@@ -240,12 +240,12 @@
status = RD4(sc, SSC_SR);
if (status == 0)
return;
+ AT91_SSC_LOCK(sc);
if (status & SSC_SR_ENDTX) {
WR4(sc, SSC_IDR, SSC_SR_ENDTX);
sc->txdone++;
wakeup(&sc->txdone);
}
- AT91_SSC_LOCK(sc);
AT91_SSC_UNLOCK(sc);
wakeup(sc);
return;
@@ -286,8 +286,12 @@
sc = arg;
if (error != 0)
return;
+ bus_dmamap_sync(sc->tag, sc->tx_map, BUS_DMASYNC_PREWRITE);
WR4(sc, PDC_TPR, segs[0].ds_addr);
WR4(sc, PDC_TCR, size);
+ WR4(sc, SSC_IER, SSC_SR_ENDTX);
+ WR4(sc, SSC_CR, SSC_CR_TXEN);
+ WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN);
}
static int
@@ -308,17 +312,16 @@
return (EINVAL);
WR4(sc, SSC_CR, SSC_CR_TXDIS);
WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS);
+ txdone = sc->txdone;
err = bus_dmamap_load_uio(sc->tag, sc->tx_map, uio, at91_ssc_loadwrite,
sc, 0);
- if (err != 0)
+ if (err != 0 && err != EINPROGRESS)
return (err);
- WR4(sc, SSC_IER, SSC_SR_ENDTX);
- WR4(sc, SSC_CR, SSC_CR_TXEN);
- WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN);
- txdone = sc->txdone;
do {
- err = msleep(&sc->txdone, NULL, PCATCH | PZERO, "sscwr", hz);
+ err = msleep(&sc->txdone, &sc->sc_mtx, PCATCH | PZERO,
+ "sscwr", hz);
} while (txdone == sc->txdone && err != EINTR);
+ bus_dmamap_sync(sc->tag, sc->tx_map, BUS_DMASYNC_POSTWRITE);
if (err == 0)
uio->uio_resid = 0;
return err;
More information about the p4-projects
mailing list