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