Date: Thu, 21 Nov 2019 02:41:22 +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: r354930 - head/sys/arm/broadcom/bcm2835 Message-ID: <201911210241.xAL2fMCZ042942@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kevans Date: Thu Nov 21 02:41:22 2019 New Revision: 354930 URL: https://svnweb.freebsd.org/changeset/base/354930 Log: bcm2835_sdhci: clean up DMA segments in error handling path Later parts assume that this would've been done if interrupts are enabled, but this is the only case in which that wouldn't have been true. This commit also reorders operations such that we're done touching slot/slot->intmask before we call back into the SDHCI framework and exit. 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 01:24:49 2019 (r354929) +++ head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c Thu Nov 21 02:41:22 2019 (r354930) @@ -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); } @@ -654,6 +655,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 +739,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 +764,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?201911210241.xAL2fMCZ042942>