diff options
author | Luiz Otavio O Souza <loos@FreeBSD.org> | 2017-05-09 19:01:57 +0000 |
---|---|---|
committer | Luiz Otavio O Souza <loos@FreeBSD.org> | 2017-05-09 19:01:57 +0000 |
commit | 915780d7642db2677a54d56cc3cfbbfe3f849b6a (patch) | |
tree | 82d277e8bc9831dea933de7e159a4291bac39c5b | |
parent | da880f61cabe70119930bf3eb12a04ac7db51c3b (diff) | |
download | src-915780d7642db2677a54d56cc3cfbbfe3f849b6a.tar.gz src-915780d7642db2677a54d56cc3cfbbfe3f849b6a.zip |
Add a new SDHCI quirk, SDHCI_QUIRK_BROKEN_AUTO_STOP, to workaround
controllers that do not support or have broken ACMD12 implementations.
Reviewed by: jmcneill
Obtained from: NetBSD
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC (Netgate)
Differential Revision: https://reviews.freebsd.org/D10602
Notes
Notes:
svn path=/head/; revision=318095
-rw-r--r-- | sys/dev/sdhci/sdhci.c | 14 | ||||
-rw-r--r-- | sys/dev/sdhci/sdhci.h | 2 |
2 files changed, 10 insertions, 6 deletions
diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c index 26602ec57b4c..68ff1db715b1 100644 --- a/sys/dev/sdhci/sdhci.c +++ b/sys/dev/sdhci/sdhci.c @@ -1060,7 +1060,7 @@ sdhci_set_transfer_mode(struct sdhci_slot *slot, struct mmc_data *data) mode |= SDHCI_TRNS_MULTI; if (data->flags & MMC_DATA_READ) mode |= SDHCI_TRNS_READ; - if (slot->req->stop) + if (slot->req->stop && !(slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP)) mode |= SDHCI_TRNS_ACMD12; if (slot->flags & SDHCI_USE_DMA) mode |= SDHCI_TRNS_DMA; @@ -1305,7 +1305,8 @@ sdhci_finish_data(struct sdhci_slot *slot) slot->intmask |= SDHCI_INT_RESPONSE); } /* Unload rest of data from DMA buffer. */ - if (!slot->data_done && (slot->flags & SDHCI_USE_DMA)) { + if (!slot->data_done && (slot->flags & SDHCI_USE_DMA) && + slot->curcmd->data != NULL) { if (data->flags & MMC_DATA_READ) { left = data->len - slot->offset; bus_dmamap_sync(slot->dmatag, slot->dmamap, @@ -1343,17 +1344,18 @@ sdhci_start(struct sdhci_slot *slot) sdhci_start_command(slot, req->cmd); return; } -/* We don't need this until using Auto-CMD12 feature - if (!(slot->flags & STOP_STARTED) && req->stop) { + if ((slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP) && + !(slot->flags & STOP_STARTED) && req->stop) { slot->flags |= STOP_STARTED; sdhci_start_command(slot, req->stop); return; } -*/ if (sdhci_debug > 1) slot_printf(slot, "result: %d\n", req->cmd->error); if (!req->cmd->error && - (slot->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) { + ((slot->curcmd == req->stop && + (slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP)) || + (slot->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) { sdhci_reset(slot, SDHCI_RESET_CMD); sdhci_reset(slot, SDHCI_RESET_DATA); } diff --git a/sys/dev/sdhci/sdhci.h b/sys/dev/sdhci/sdhci.h index 0b299150b990..814f81ed5407 100644 --- a/sys/dev/sdhci/sdhci.h +++ b/sys/dev/sdhci/sdhci.h @@ -87,6 +87,8 @@ #define SDHCI_QUIRK_CAPS_BIT63_FOR_MMC_HS400 (1 << 26) /* Controller support for SDHCI_CTRL2_PRESET_VALUE is broken. */ #define SDHCI_QUIRK_PRESET_VALUE_BROKEN (1 << 27) +/* Controller does not support or the support for ACMD12 is broken. */ +#define SDHCI_QUIRK_BROKEN_AUTO_STOP (1 << 28) /* * Controller registers |