summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2013-08-18 19:08:53 +0000
committerian <ian@FreeBSD.org>2013-08-18 19:08:53 +0000
commit2fe1b528a90e21592c13868df75e787ff330d3d7 (patch)
tree4f62af8f35ca8af52fedfb235e8ad9413b6aff8a
parenteb608cee6363c1e5f1bd19a23b138a3716e74aa4 (diff)
downloadFreeBSD-src-2fe1b528a90e21592c13868df75e787ff330d3d7.zip
FreeBSD-src-2fe1b528a90e21592c13868df75e787ff330d3d7.tar.gz
Add a new SDHCI_QUIRK_DONT_SHIFT_RESPONSE for hardware that pre-shifts
the response bits the way we do in software. While the hardware is just doing the sensible thing rather than leaving it to the software, it's in violation of the spec by doing so. Grrrr.
-rw-r--r--sys/dev/sdhci/sdhci.c9
-rw-r--r--sys/dev/sdhci/sdhci.h2
2 files changed, 9 insertions, 2 deletions
diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c
index c4afb8a..1fc1358 100644
--- a/sys/dev/sdhci/sdhci.c
+++ b/sys/dev/sdhci/sdhci.c
@@ -835,8 +835,13 @@ sdhci_finish_command(struct sdhci_slot *slot)
uint8_t extra = 0;
for (i = 0; i < 4; i++) {
uint32_t val = RD4(slot, SDHCI_RESPONSE + i * 4);
- slot->curcmd->resp[3 - i] = (val << 8) + extra;
- extra = val >> 24;
+ if (slot->quirks & SDHCI_QUIRK_DONT_SHIFT_RESPONSE)
+ slot->curcmd->resp[3 - i] = val;
+ else {
+ slot->curcmd->resp[3 - i] =
+ (val << 8) | extra;
+ extra = val >> 24;
+ }
}
} else
slot->curcmd->resp[0] = RD4(slot, SDHCI_RESPONSE);
diff --git a/sys/dev/sdhci/sdhci.h b/sys/dev/sdhci/sdhci.h
index cda845c..d136409 100644
--- a/sys/dev/sdhci/sdhci.h
+++ b/sys/dev/sdhci/sdhci.h
@@ -57,6 +57,8 @@
#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<11)
/* SDHCI_CAPABILITIES is invalid */
#define SDHCI_QUIRK_MISSING_CAPS (1<<12)
+/* Hardware shifts the 136-bit response, don't do it in software. */
+#define SDHCI_QUIRK_DONT_SHIFT_RESPONSE (1<<13)
/*
* Controller registers
OpenPOWER on IntegriCloud