From 3e6b663e1fe25ee947a722b1c0555e6d97a1a9ab Mon Sep 17 00:00:00 2001 From: ian Date: Fri, 13 Feb 2015 18:13:42 +0000 Subject: MFC r277027: Handle the possibility that SDHCI_PLATFORM_START_TRANSFER() can fail. --- sys/dev/sdhci/sdhci.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c index 503cbf3..bb99937 100644 --- a/sys/dev/sdhci/sdhci.c +++ b/sys/dev/sdhci/sdhci.c @@ -985,7 +985,6 @@ sdhci_finish_data(struct sdhci_slot *slot) { struct mmc_data *data = slot->curcmd->data; - slot->data_done = 1; /* Interrupt aggregation: Restore command interrupt. * Auxiliary restore point for the case when data interrupt * happened first. */ @@ -994,7 +993,7 @@ sdhci_finish_data(struct sdhci_slot *slot) slot->intmask |= SDHCI_INT_RESPONSE); } /* Unload rest of data from DMA buffer. */ - if (slot->flags & SDHCI_USE_DMA) { + if (!slot->data_done && (slot->flags & SDHCI_USE_DMA)) { if (data->flags & MMC_DATA_READ) { size_t left = data->len - slot->offset; bus_dmamap_sync(slot->dmatag, slot->dmamap, @@ -1005,6 +1004,7 @@ sdhci_finish_data(struct sdhci_slot *slot) bus_dmamap_sync(slot->dmatag, slot->dmamap, BUS_DMASYNC_POSTWRITE); } + slot->data_done = 1; /* If there was error - reset the host. */ if (slot->curcmd->error) { sdhci_reset(slot, SDHCI_RESET_CMD); @@ -1172,12 +1172,7 @@ sdhci_data_irq(struct sdhci_slot *slot, uint32_t intmask) } if (slot->curcmd->error) { /* No need to continue after any error. */ - if (slot->flags & PLATFORM_DATA_STARTED) { - slot->flags &= ~PLATFORM_DATA_STARTED; - SDHCI_PLATFORM_FINISH_TRANSFER(slot->bus, slot); - } else - sdhci_finish_data(slot); - return; + goto done; } /* Handle PIO interrupt. */ @@ -1234,6 +1229,15 @@ sdhci_data_irq(struct sdhci_slot *slot, uint32_t intmask) } else sdhci_finish_data(slot); } +done: + if (slot->curcmd != NULL && slot->curcmd->error != 0) { + if (slot->flags & PLATFORM_DATA_STARTED) { + slot->flags &= ~PLATFORM_DATA_STARTED; + SDHCI_PLATFORM_FINISH_TRANSFER(slot->bus, slot); + } else + sdhci_finish_data(slot); + return; + } } static void -- cgit v1.1