Author: bz Date: Sat Jun 8 16:15:00 2019 New Revision: 348804 URL: https://svnweb.freebsd.org/changeset/base/348804
Log: bcm2835_sdhci.c: exit DMA if not enough data left to avoid timeout errors In the DMA case, given we disable the data interrupts, we never seem to get DATA_END. Given we are relying on DMA interrupts we are not using the SDHCI state machine and hence only call into sdhci_platform_will_handle() for the first check of data. We do not call "will handle" for any following round trips of the same transaction if block size * count > BCM_DMA_BLOCK_SIZE. Manually check "left" in the DMA interrupt handler to see if we have at least another full BCM_DMA_BLOCK_SIZE to handle. Without this change we would DMA that and then even start a DMA with left == 0 which would lead to a timeout and error. Now we re-enable data interrupts and return and let the SDHCI generic interrupt handler and state machine pick the SPACE_AVAIL up and then find that it should punt to the pio_handler for the remaining bytes or finish the data transaction. With this change block mode seems to work beyond 7 * 64byte blocks, which worked as it was below BCM_DMA_BLOCK_SIZE. MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D20199 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 Sat Jun 8 16:05:43 2019 (r348803) +++ head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c Sat Jun 8 16:15:00 2019 (r348804) @@ -539,6 +539,22 @@ bcm_sdhci_dma_intr(int ch, void *arg) left = min(BCM_SDHCI_BUFFER_SIZE, slot->curcmd->data->len - slot->offset); + /* + * If there is less than buffer size outstanding, we would not handle + * it anymore using DMA if bcm_sdhci_will_handle_transfer() were asked. + * Re-enable interrupts and return and let the SDHCI state machine + * finish the job. + */ + if (left < BCM_SDHCI_BUFFER_SIZE) { + /* Re-enable data interrupts. */ + slot->intmask |= SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | + SDHCI_INT_DATA_END; + bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE, + slot->intmask); + mtx_unlock(&slot->mtx); + return; + } + /* DATA END? */ reg = bcm_sdhci_read_4(slot->bus, slot, SDHCI_INT_STATUS); _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"