mmc: fix response decoding on little endian
authorRabin Vincent <rabin@rab.in>
Sun, 5 Apr 2009 08:00:55 +0000 (13:30 +0530)
committerAndy Fleming <afleming@freescale.com>
Tue, 2 Jun 2009 22:18:57 +0000 (17:18 -0500)
The mmc code defines the response as an array of chars.  However, it
access the response bytes both as (i) an array of four uints (with
casts) and (ii) as individual chars.  The former case is used more
often, including by the driver when it assigns the response.

The char-wise accesses are broken on little endian systems because they
assume that the bytes in the uints are in big endian byte order.

This patch fixes this by changing the response to be an array of four
uints and replacing the char-wise accesses with equivalent uint-wise
accesses.

Signed-off-by: Rabin Vincent <rabin@rab.in>
drivers/mmc/mmc.c
include/mmc.h

index 95ed21eb0ad2fa8c4c2107f19ab3336abf71fef7..1c89e314270fb2bfef98d824f34854259013676d 100644 (file)
@@ -651,7 +651,7 @@ int mmc_startup(struct mmc *mmc)
        mmc->csd[3] = ((uint *)(cmd.response))[3];
 
        if (mmc->version == MMC_VERSION_UNKNOWN) {
-               int version = (cmd.response[0] >> 2) & 0xf;
+               int version = (cmd.response[0] >> 26) & 0xf;
 
                switch (version) {
                        case 0:
@@ -676,8 +676,8 @@ int mmc_startup(struct mmc *mmc)
        }
 
        /* divide frequency by 10, since the mults are 10x bigger */
-       freq = fbase[(cmd.response[3] & 0x7)];
-       mult = multipliers[((cmd.response[3] >> 3) & 0xf)];
+       freq = fbase[(cmd.response[0] & 0x7)];
+       mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
 
        mmc->tran_speed = freq * mult;
 
@@ -791,13 +791,13 @@ int mmc_startup(struct mmc *mmc)
        mmc->block_dev.type = 0;
        mmc->block_dev.blksz = mmc->read_bl_len;
        mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
-       sprintf(mmc->block_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x%02x",
-                       mmc->cid[0], mmc->cid[1], mmc->cid[2],
-                       mmc->cid[9], mmc->cid[10], mmc->cid[11], mmc->cid[12]);
-       sprintf(mmc->block_dev.product,"%c%c%c%c%c", mmc->cid[3],
-                       mmc->cid[4], mmc->cid[5], mmc->cid[6], mmc->cid[7]);
-       sprintf(mmc->block_dev.revision,"%d.%d", mmc->cid[8] >> 4,
-                       mmc->cid[8] & 0xf);
+       sprintf(mmc->block_dev.vendor, "Man %06x Snr %08x", mmc->cid[0] >> 8,
+                       (mmc->cid[2] << 8) | (mmc->cid[3] >> 24));
+       sprintf(mmc->block_dev.product, "%c%c%c%c%c", mmc->cid[0] & 0xff,
+                       (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
+                       (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
+       sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28,
+                       (mmc->cid[2] >> 24) & 0xf);
        init_part(&mmc->block_dev);
 
        return 0;
index b9b27ba1817ec07ec0f3290aae1bff06acb88c25..229d494ff76de458e7150f0bac907c1cb6077c26 100644 (file)
@@ -91,7 +91,7 @@
 #define MMC_HS_TIMING          0x00000100
 #define MMC_HS_52MHZ           0x2
 
-#define OCR_BUSY       0x80
+#define OCR_BUSY       0x80000000
 #define OCR_HCS                0x40000000
 
 #define MMC_VDD_165_195                0x00000080      /* VDD voltage 1.65 - 1.95 */
@@ -223,7 +223,7 @@ struct mmc_cmd {
        ushort cmdidx;
        uint resp_type;
        uint cmdarg;
-       char response[18];
+       uint response[4];
        uint flags;
 };
 
@@ -253,7 +253,7 @@ struct mmc {
        uint ocr;
        uint scr[2];
        uint csd[4];
-       char cid[16];
+       uint cid[4];
        ushort rca;
        uint tran_speed;
        uint read_bl_len;