Date: Wed, 25 Oct 2006 21:02:27 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 108436 for review Message-ID: <200610252102.k9PL2RTK082984@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=108436 Change 108436 by imp@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610252102.k9PL2RTK082984>