]> git.sur5r.net Git - u-boot/blobdiff - drivers/mmc/mmc.c
mmc: fix response decoding on little endian
[u-boot] / drivers / mmc / mmc.c
index 7791c3896e98a00461bda3d4f18bb55d599bad82..1c89e314270fb2bfef98d824f34854259013676d 100644 (file)
@@ -31,6 +31,7 @@
 #include <malloc.h>
 #include <linux/list.h>
 #include <mmc.h>
+#include <div64.h>
 
 static struct list_head mmc_devices;
 static int cur_dev_num = -1;
@@ -155,8 +156,8 @@ int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size)
        char *buffer;
        int i;
        int blklen = mmc->read_bl_len;
-       int startblock = src / blklen;
-       int endblock = (src + size - 1) / blklen;
+       int startblock = lldiv(src, mmc->read_bl_len);
+       int endblock = lldiv(src + size - 1, mmc->read_bl_len);
        int err = 0;
 
        /* Make a buffer big enough to hold all the blocks we might read */
@@ -650,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:
@@ -675,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;
 
@@ -789,14 +790,14 @@ int mmc_startup(struct mmc *mmc)
        mmc->block_dev.lun = 0;
        mmc->block_dev.type = 0;
        mmc->block_dev.blksz = mmc->read_bl_len;
-       mmc->block_dev.lba = 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);
+       mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
+       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;
@@ -846,7 +847,7 @@ block_dev_desc_t *mmc_get_dev(int dev)
 {
        struct mmc *mmc = find_mmc_device(dev);
 
-       return &mmc->block_dev;
+       return mmc ? &mmc->block_dev : NULL;
 }
 
 int mmc_init(struct mmc *mmc)