Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/sdmmc Make PIO on normal SDHC devices work correctly...
details: https://anonhg.NetBSD.org/src/rev/af7d66787e1f
branches: trunk
changeset: 780572:af7d66787e1f
user: matt <matt%NetBSD.org@localhost>
date: Mon Jul 30 00:56:01 2012 +0000
description:
Make PIO on normal SDHC devices work correctly on big-endian machines.
Add locking around interrupt manipulation (it should now be MP safe).
diffstat:
sys/dev/sdmmc/sdhc.c | 37 +++++++++++++++++++++++--------------
1 files changed, 23 insertions(+), 14 deletions(-)
diffs (175 lines):
diff -r 0cd0020e8109 -r af7d66787e1f sys/dev/sdmmc/sdhc.c
--- a/sys/dev/sdmmc/sdhc.c Mon Jul 30 00:53:59 2012 +0000
+++ b/sys/dev/sdmmc/sdhc.c Mon Jul 30 00:56:01 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sdhc.c,v 1.28 2012/07/28 23:02:57 matt Exp $ */
+/* $NetBSD: sdhc.c,v 1.29 2012/07/30 00:56:01 matt Exp $ */
/* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */
/*
@@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.28 2012/07/28 23:02:57 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.29 2012/07/30 00:56:01 matt Exp $");
#ifdef _KERNEL_OPT
#include "opt_sdmmc.h"
@@ -336,7 +336,7 @@
* capabilities. (2.2.15)
*/
HWRITE1(hp, SDHC_TIMEOUT_CTL, SDHC_TIMEOUT_MAX);
-#if 0
+#if 1
if (ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED))
HWRITE4(hp, SDHC_NINTR_STATUS, SDHC_CMD_TIMEOUT_ERROR << 16);
#endif
@@ -552,12 +552,13 @@
/* Set data timeout counter value to max for now. */
HWRITE1(hp, SDHC_TIMEOUT_CTL, SDHC_TIMEOUT_MAX);
-#if 0
+#if 1
if (ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED))
HWRITE4(hp, SDHC_NINTR_STATUS, SDHC_CMD_TIMEOUT_ERROR << 16);
#endif
/* Enable interrupts. */
+ mutex_enter(&hp->intr_mtx);
sdhcimask = SDHC_CARD_REMOVAL | SDHC_CARD_INSERTION |
SDHC_BUFFER_READ_READY | SDHC_BUFFER_WRITE_READY |
SDHC_DMA_INTERRUPT | SDHC_BLOCK_GAP_EVENT |
@@ -576,6 +577,7 @@
HWRITE2(hp, SDHC_NINTR_SIGNAL_EN, sdhcimask);
HWRITE2(hp, SDHC_EINTR_SIGNAL_EN, SDHC_EINTR_SIGNAL_MASK);
}
+ mutex_exit(&hp->intr_mtx);
out:
return error;
@@ -936,7 +938,7 @@
struct sdhc_host *hp = (struct sdhc_host *)sch;
if (!ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) {
- mutex_enter(&hp->host_mtx);
+ mutex_enter(&hp->intr_mtx);
if (enable) {
HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
HSET2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
@@ -944,7 +946,7 @@
HCLR2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
}
- mutex_exit(&hp->host_mtx);
+ mutex_exit(&hp->intr_mtx);
}
}
@@ -954,9 +956,9 @@
struct sdhc_host *hp = (struct sdhc_host *)sch;
if (!ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) {
- mutex_enter(&hp->host_mtx);
+ mutex_enter(&hp->intr_mtx);
HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
- mutex_exit(&hp->host_mtx);
+ mutex_exit(&hp->intr_mtx);
}
}
@@ -984,6 +986,7 @@
if (cmd->c_data && ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) {
const uint16_t ready = SDHC_BUFFER_READ_READY | SDHC_BUFFER_WRITE_READY;
+ mutex_enter(&hp->intr_mtx);
if (ISSET(hp->flags, SHF_USE_DMA)) {
HCLR2(hp, SDHC_NINTR_SIGNAL_EN, ready);
HCLR2(hp, SDHC_NINTR_STATUS_EN, ready);
@@ -991,6 +994,7 @@
HSET2(hp, SDHC_NINTR_SIGNAL_EN, ready);
HSET2(hp, SDHC_NINTR_STATUS_EN, ready);
}
+ mutex_exit(&hp->intr_mtx);
}
/*
@@ -1284,11 +1288,13 @@
while (datalen > 0) {
if (!ISSET(HREAD4(hp, SDHC_PRESENT_STATE), imask)) {
+ mutex_enter(&hp->intr_mtx);
if (ISSET(hp->sc->sc_flags, SDHC_FLAG_32BIT_ACCESS)) {
HSET4(hp, SDHC_NINTR_SIGNAL_EN, imask);
} else {
HSET2(hp, SDHC_NINTR_SIGNAL_EN, imask);
}
+ mutex_exit(&hp->intr_mtx);
if (!sdhc_wait_intr(hp, imask, SDHC_BUFFER_TIMEOUT)) {
error = ETIMEDOUT;
break;
@@ -1321,12 +1327,12 @@
if (((__uintptr_t)data & 3) == 0) {
while (datalen > 3) {
- *(uint32_t *)data = HREAD4(hp, SDHC_DATA);
+ *(uint32_t *)data = le32toh(HREAD4(hp, SDHC_DATA));
data += 4;
datalen -= 4;
}
if (datalen > 1) {
- *(uint16_t *)data = HREAD2(hp, SDHC_DATA);
+ *(uint16_t *)data = le16toh(HREAD2(hp, SDHC_DATA));
data += 2;
datalen -= 2;
}
@@ -1337,7 +1343,7 @@
}
} else if (((__uintptr_t)data & 1) == 0) {
while (datalen > 1) {
- *(uint16_t *)data = HREAD2(hp, SDHC_DATA);
+ *(uint16_t *)data = le16toh(HREAD2(hp, SDHC_DATA));
data += 2;
datalen -= 2;
}
@@ -1361,12 +1367,12 @@
if (((__uintptr_t)data & 3) == 0) {
while (datalen > 3) {
- HWRITE4(hp, SDHC_DATA, *(uint32_t *)data);
+ HWRITE4(hp, SDHC_DATA, htole32(*(uint32_t *)data));
data += 4;
datalen -= 4;
}
if (datalen > 1) {
- HWRITE2(hp, SDHC_DATA, *(uint16_t *)data);
+ HWRITE2(hp, SDHC_DATA, htole16(*(uint16_t *)data));
data += 2;
datalen -= 2;
}
@@ -1377,7 +1383,7 @@
}
} else if (((__uintptr_t)data & 1) == 0) {
while (datalen > 1) {
- HWRITE2(hp, SDHC_DATA, *(uint16_t *)data);
+ HWRITE2(hp, SDHC_DATA, htole16(*(uint16_t *)data));
data += 2;
datalen -= 2;
}
@@ -1578,6 +1584,8 @@
DPRINTF(2,("%s: interrupt status=%x error=%x\n", HDEVNAME(hp),
status, error));
+ mutex_enter(&hp->intr_mtx);
+
/* Claim this interrupt. */
done = 1;
@@ -1628,6 +1636,7 @@
HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
sdmmc_card_intr(hp->sdmmc);
}
+ mutex_exit(&hp->intr_mtx);
}
return done;
Home |
Main Index |
Thread Index |
Old Index