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.
This commit is contained in:
parent
b61ac06706
commit
a8761a2a55
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=354933
@ -606,6 +606,25 @@ bcm_sdhci_dma_exit(struct bcm_sdhci_softc *sc)
|
||||
slot->intmask);
|
||||
}
|
||||
|
||||
static void
|
||||
bcm_sdhci_dma_unload(struct bcm_sdhci_softc *sc)
|
||||
{
|
||||
struct sdhci_slot *slot = &sc->sc_slot;
|
||||
|
||||
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);
|
||||
else
|
||||
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
bus_dmamap_unload(sc->sc_dma_tag, sc->sc_dma_map);
|
||||
|
||||
sc->dmamap_seg_count = 0;
|
||||
sc->dmamap_seg_index = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
bcm_sdhci_dma_intr(int ch, void *arg)
|
||||
{
|
||||
@ -626,18 +645,7 @@ 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);
|
||||
else
|
||||
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
bus_dmamap_unload(sc->sc_dma_tag, sc->sc_dma_map);
|
||||
|
||||
sc->dmamap_seg_count = 0;
|
||||
sc->dmamap_seg_index = 0;
|
||||
bcm_sdhci_dma_unload(sc);
|
||||
|
||||
/*
|
||||
* If we had no further segments pending, we need to determine how to
|
||||
@ -654,8 +662,10 @@ bcm_sdhci_dma_intr(int ch, void *arg)
|
||||
|
||||
bcm_sdhci_start_dma(slot);
|
||||
if (slot->curcmd->error != 0) {
|
||||
sdhci_finish_data(slot);
|
||||
/* We won't recover from this error for this command. */
|
||||
bcm_sdhci_dma_unload(sc);
|
||||
bcm_sdhci_dma_exit(sc);
|
||||
sdhci_finish_data(slot);
|
||||
}
|
||||
} else if ((reg & SDHCI_INT_DATA_END) != 0) {
|
||||
bcm_sdhci_dma_exit(sc);
|
||||
@ -754,16 +764,7 @@ bcm_sdhci_finish_transfer(device_t dev, struct sdhci_slot *slot)
|
||||
* regressed to SDHCI-driven PIO to finish the operation and
|
||||
* this is certainly caused by developer-error.
|
||||
*/
|
||||
if (slot->curcmd->data->flags & MMC_DATA_READ)
|
||||
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
else
|
||||
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
bus_dmamap_unload(sc->sc_dma_tag, sc->sc_dma_map);
|
||||
|
||||
sc->dmamap_seg_count = 0;
|
||||
sc->dmamap_seg_index = 0;
|
||||
bcm_sdhci_dma_unload(sc);
|
||||
}
|
||||
|
||||
sdhci_finish_data(slot);
|
||||
|
Loading…
Reference in New Issue
Block a user