Date: Thu, 21 Nov 2019 02:47:55 +0000 (UTC) From: Kyle Evans <kevans@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354932 - head/sys/arm/broadcom/bcm2835 Message-ID: <201911210247.xAL2ltl8046218@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kevans Date: Thu Nov 21 02:47:55 2019 New Revision: 354932 URL: https://svnweb.freebsd.org/changeset/base/354932 Log: bcm2835_sdhci: roll back r354823 r354823 kicked DATA_END handling out of the DMA interrupt path "to make things easy", but this was likely a mistake -- if we know we're done after we've finished pending DMA operations, we should go ahead and acknowledge it rather than waiting for the controller to finalize it. If it's not ready, we'll simply re-enable interrupts and wait for it anyways, to be re-entered in sdhci_data_intr. Modified: head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c Modified: head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c ============================================================================== --- head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c Thu Nov 21 02:44:05 2019 (r354931) +++ head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c Thu Nov 21 02:47:55 2019 (r354932) @@ -87,6 +87,7 @@ __FBSDID("$FreeBSD$"); rounddown(BCM_SDHCI_SLOT_LEFT(slot), BCM_SDHCI_BUFFER_SIZE)) #define DATA_PENDING_MASK (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL) +#define DATA_XFER_MASK (DATA_PENDING_MASK | SDHCI_INT_DATA_END) #ifdef DEBUG static int bcm2835_sdhci_debug = 0; @@ -579,7 +580,7 @@ bcm_sdhci_start_dma_seg(struct bcm_sdhci_softc *sc) if (idx == 0) { bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, sync_op); - slot->intmask &= ~DATA_PENDING_MASK; + slot->intmask &= ~DATA_XFER_MASK; bcm_sdhci_write_4(sc->sc_dev, slot, SDHCI_SIGNAL_ENABLE, slot->intmask); } @@ -600,7 +601,7 @@ bcm_sdhci_dma_exit(struct bcm_sdhci_softc *sc) mtx_assert(&slot->mtx, MA_OWNED); /* Re-enable interrupts */ - slot->intmask |= DATA_PENDING_MASK; + slot->intmask |= DATA_XFER_MASK; bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE, slot->intmask); } @@ -625,6 +626,8 @@ bcm_sdhci_dma_intr(int ch, void *arg) goto out; } + if (sc->dmamap_seg_count == 0) + return; if ((slot->curcmd->data->flags & MMC_DATA_READ) != 0) bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, BUS_DMASYNC_POSTREAD); @@ -654,6 +657,12 @@ bcm_sdhci_dma_intr(int ch, void *arg) sdhci_finish_data(slot); bcm_sdhci_dma_exit(sc); } + } else if ((reg & SDHCI_INT_DATA_END) != 0) { + bcm_sdhci_dma_exit(sc); + bcm_sdhci_write_4(slot->bus, slot, SDHCI_INT_STATUS, + reg); + slot->flags &= ~PLATFORM_DATA_STARTED; + sdhci_finish_data(slot); } else { bcm_sdhci_dma_exit(sc); } @@ -732,7 +741,11 @@ bcm_sdhci_finish_transfer(device_t dev, struct sdhci_s { struct bcm_sdhci_softc *sc = device_get_softc(slot->bus); - /* Clean up */ + /* + * Clean up. Interrupts are clearly enabled, because we received an + * SDHCI_INT_DATA_END to get this far -- just make sure we don't leave + * anything laying around. + */ if (sc->dmamap_seg_count != 0) { /* * Our segment math should have worked out such that we would @@ -753,7 +766,6 @@ bcm_sdhci_finish_transfer(device_t dev, struct sdhci_s sc->dmamap_seg_index = 0; } - bcm_sdhci_dma_exit(sc); sdhci_finish_data(slot); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911210247.xAL2ltl8046218>