From f4f32bc740cf0973714025a3bebcaadc26a080e9 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 14 Dec 2016 17:04:27 -0600 Subject: [PATCH] MMC/SD SDIO (again): This is really an endian-ness issue. Behavior should be different on big- vs little-endian machines. --- drivers/mmcsd/mmcsd_sdio.c | 152 ++++++++++++++++++++----------------- 1 file changed, 83 insertions(+), 69 deletions(-) diff --git a/drivers/mmcsd/mmcsd_sdio.c b/drivers/mmcsd/mmcsd_sdio.c index 13f86102e4..5c6df6874b 100644 --- a/drivers/mmcsd/mmcsd_sdio.c +++ b/drivers/mmcsd/mmcsd_sdio.c @@ -100,6 +100,20 @@ #define IS_EMPTY(priv) (priv->type == MMCSD_CARDTYPE_UNKNOWN) +/* Handle endian-ness */ + +#ifdef CONFIG_ENDIAN_BIG +# define NDXA 3 /* Bits n through n+7 */ +# define NDXB 2 /* Bits n+8 through n+15 */ +# define NDXC 1 /* Bits n+16 through n+23 */ +# define NDXD 0 /* Bits n+24 through n+31 */ +#else +# define NDXA 0 /* Bits n through n+7 */ +# define NDXB 1 /* Bits n+8 through n+15 */ +# define NDXC 2 /* Bits n+16 through n+23 */ +# define NDXD 3 /* Bits n+24 through n+31 */ +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -580,13 +594,13 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4]) #ifdef CONFIG_DEBUG_FS_INFO memset(&decoded, 0, sizeof(struct mmcsd_csd_s)); - decoded.csdstructure = csd[3] >> 30; - decoded.mmcspecvers = (csd[3] >> 26) & 0x0f; - decoded.taac.timevalue = (csd[3] >> 19) & 0x0f; - decoded.taac.timeunit = (csd[3] >> 16) & 7; - decoded.nsac = (csd[3] >> 8) & 0xff; - decoded.transpeed.timevalue = (csd[3] >> 3) & 0x0f; - decoded.transpeed.transferrateunit = csd[3] & 7; + decoded.csdstructure = csd[NDXD] >> 30; + decoded.mmcspecvers = (csd[NDXD] >> 26) & 0x0f; + decoded.taac.timevalue = (csd[NDXD] >> 19) & 0x0f; + decoded.taac.timeunit = (csd[NDXD] >> 16) & 7; + decoded.nsac = (csd[NDXD] >> 8) & 0xff; + decoded.transpeed.timevalue = (csd[NDXD] >> 3) & 0x0f; + decoded.transpeed.transferrateunit = csd[NDXD] & 7; #endif /* Word 2: Bits 64:95 @@ -603,15 +617,15 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4]) * C_SIZE 48:69 Device size */ - priv->dsrimp = (csd[2] >> 12) & 1; - readbllen = (csd[2] >> 16) & 0x0f; + priv->dsrimp = (csd[NDXC] >> 12) & 1; + readbllen = (csd[NDXC] >> 16) & 0x0f; #ifdef CONFIG_DEBUG_FS_INFO - decoded.ccc = (csd[2] >> 20) & 0x0fff; - decoded.readbllen = (csd[2] >> 16) & 0x0f; - decoded.readblpartial = (csd[2] >> 15) & 1; - decoded.writeblkmisalign = (csd[2] >> 14) & 1; - decoded.readblkmisalign = (csd[2] >> 13) & 1; + decoded.ccc = (csd[NDXC] >> 20) & 0x0fff; + decoded.readbllen = (csd[NDXC] >> 16) & 0x0f; + decoded.readblpartial = (csd[NDXC] >> 15) & 1; + decoded.writeblkmisalign = (csd[NDXC] >> 14) & 1; + decoded.readblkmisalign = (csd[NDXC] >> 13) & 1; decoded.dsrimp = priv->dsrimp; #endif @@ -657,7 +671,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4]) * 512*1024 = (1 << 19) */ - uint32_t csize = ((csd[2] & 0x3f) << 16) | (csd[1] >> 16); + uint32_t csize = ((csd[NDXC] & 0x3f) << 16) | (csd[NDXB] >> 16); #ifdef CONFIG_HAVE_LONG_LONG priv->capacity = ((uint64_t)(csize + 1)) << 19; #else @@ -669,9 +683,9 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4]) #ifdef CONFIG_DEBUG_FS_INFO decoded.u.sdblock.csize = csize; - decoded.u.sdblock.sderblen = (csd[1] >> 14) & 1; - decoded.u.sdblock.sdsectorsize = (csd[1] >> 7) & 0x7f; - decoded.u.sdblock.sdwpgrpsize = csd[1] & 0x7f; + decoded.u.sdblock.sderblen = (csd[NDXB] >> 14) & 1; + decoded.u.sdblock.sdsectorsize = (csd[NDXB] >> 7) & 0x7f; + decoded.u.sdblock.sdwpgrpsize = csd[NDXB] & 0x7f; #endif } else @@ -681,8 +695,8 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4]) * C_SIZE: 73:64 from Word 2 and 63:62 from Word 3 */ - uint16_t csize = ((csd[2] & 0x03ff) << 2) | ((csd[1] >> 30) & 3); - uint8_t csizemult = (csd[1] >> 15) & 7; + uint16_t csize = ((csd[NDXC] & 0x03ff) << 2) | ((csd[NDXB] >> 30) & 3); + uint8_t csizemult = (csd[NDXB] >> 15) & 7; priv->nblocks = ((uint32_t)csize + 1) * (1 << (csizemult + 2)); priv->blockshift = readbllen; @@ -707,27 +721,27 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4]) if (IS_SD(priv->type)) { decoded.u.sdbyte.csize = csize; - decoded.u.sdbyte.vddrcurrmin = (csd[1] >> 27) & 7; - decoded.u.sdbyte.vddrcurrmax = (csd[1] >> 24) & 7; - decoded.u.sdbyte.vddwcurrmin = (csd[1] >> 21) & 7; - decoded.u.sdbyte.vddwcurrmax = (csd[1] >> 18) & 7; + decoded.u.sdbyte.vddrcurrmin = (csd[NDXB] >> 27) & 7; + decoded.u.sdbyte.vddrcurrmax = (csd[NDXB] >> 24) & 7; + decoded.u.sdbyte.vddwcurrmin = (csd[NDXB] >> 21) & 7; + decoded.u.sdbyte.vddwcurrmax = (csd[NDXB] >> 18) & 7; decoded.u.sdbyte.csizemult = csizemult; - decoded.u.sdbyte.sderblen = (csd[1] >> 14) & 1; - decoded.u.sdbyte.sdsectorsize = (csd[1] >> 7) & 0x7f; - decoded.u.sdbyte.sdwpgrpsize = csd[1] & 0x7f; + decoded.u.sdbyte.sderblen = (csd[NDXB] >> 14) & 1; + decoded.u.sdbyte.sdsectorsize = (csd[NDXB] >> 7) & 0x7f; + decoded.u.sdbyte.sdwpgrpsize = csd[NDXB] & 0x7f; } #ifdef CONFIG_MMCSD_MMCSUPPORT else if (IS_MMC(priv->type)) { decoded.u.mmc.csize = csize; - decoded.u.mmc.vddrcurrmin = (csd[1] >> 27) & 7; - decoded.u.mmc.vddrcurrmax = (csd[1] >> 24) & 7; - decoded.u.mmc.vddwcurrmin = (csd[1] >> 21) & 7; - decoded.u.mmc.vddwcurrmax = (csd[1] >> 18) & 7; + decoded.u.mmc.vddrcurrmin = (csd[NDXB] >> 27) & 7; + decoded.u.mmc.vddrcurrmax = (csd[NDXB] >> 24) & 7; + decoded.u.mmc.vddwcurrmin = (csd[NDXB] >> 21) & 7; + decoded.u.mmc.vddwcurrmax = (csd[NDXB] >> 18) & 7; decoded.u.mmc.csizemult = csizemult; - decoded.u.mmc.er.mmc22.sectorsize = (csd[1] >> 10) & 0x1f; - decoded.u.mmc.er.mmc22.ergrpsize = (csd[1] >> 5) & 0x1f; - decoded.u.mmc.mmcwpgrpsize = csd[1] & 0x1f; + decoded.u.mmc.er.mmc22.sectorsize = (csd[NDXB] >> 10) & 0x1f; + decoded.u.mmc.er.mmc22.ergrpsize = (csd[NDXB] >> 5) & 0x1f; + decoded.u.mmc.mmcwpgrpsize = csd[NDXB] & 0x1f; } #endif #endif @@ -749,23 +763,23 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4]) * Not used 0:0 */ - permwriteprotect = (csd[0] >> 13) & 1; - tmpwriteprotect = (csd[0] >> 12) & 1; + permwriteprotect = (csd[NDXA] >> 13) & 1; + tmpwriteprotect = (csd[NDXA] >> 12) & 1; priv->wrprotect = (permwriteprotect || tmpwriteprotect); #ifdef CONFIG_DEBUG_FS_INFO - decoded.wpgrpen = csd[0] >> 31; - decoded.mmcdfltecc = (csd[0] >> 29) & 3; - decoded.r2wfactor = (csd[0] >> 26) & 7; - decoded.writebllen = (csd[0] >> 22) & 0x0f; - decoded.writeblpartial = (csd[0] >> 21) & 1; - decoded.fileformatgrp = (csd[0] >> 15) & 1; - decoded.copy = (csd[0] >> 14) & 1; + decoded.wpgrpen = csd[NDXA] >> 31; + decoded.mmcdfltecc = (csd[NDXA] >> 29) & 3; + decoded.r2wfactor = (csd[NDXA] >> 26) & 7; + decoded.writebllen = (csd[NDXA] >> 22) & 0x0f; + decoded.writeblpartial = (csd[NDXA] >> 21) & 1; + decoded.fileformatgrp = (csd[NDXA] >> 15) & 1; + decoded.copy = (csd[NDXA] >> 14) & 1; decoded.permwriteprotect = permwriteprotect; decoded.tmpwriteprotect = tmpwriteprotect; - decoded.fileformat = (csd[0] >> 10) & 3; - decoded.mmcecc = (csd[0] >> 8) & 3; - decoded.crc = (csd[0] >> 1) & 0x7f; + decoded.fileformat = (csd[NDXA] >> 10) & 3; + decoded.mmcecc = (csd[NDXA] >> 8) & 3; + decoded.crc = (csd[NDXA] >> 1) & 0x7f; finfo("CSD:\n"); finfo(" CSD_STRUCTURE: %d SPEC_VERS: %d (MMC)\n", @@ -856,9 +870,9 @@ static void mmcsd_decodeCID(FAR struct mmcsd_state_s *priv, uint32_t cid[4]) * pnm[0] 103:96 */ - decoded.mid = cid[3] >> 24; - decoded.oid = (cid[3] >> 8) & 0xffff; - decoded.pnm[0] = cid[3] & 0xff; + decoded.mid = cid[NDXD] >> 24; + decoded.oid = (cid[NDXD] >> 8) & 0xffff; + decoded.pnm[0] = cid[NDXD] & 0xff; /* Word 2: Bits 64:95 * pnm - 103-64 40-bit Product Name (ascii) + null terminator @@ -868,10 +882,10 @@ static void mmcsd_decodeCID(FAR struct mmcsd_state_s *priv, uint32_t cid[4]) * pnm[4] 71:64 */ - decoded.pnm[1] = cid[2] >> 24; - decoded.pnm[2] = (cid[2] >> 16) & 0xff; - decoded.pnm[3] = (cid[2] >> 8) & 0xff; - decoded.pnm[4] = cid[2] & 0xff; + decoded.pnm[1] = cid[NDXC] >> 24; + decoded.pnm[2] = (cid[NDXC] >> 16) & 0xff; + decoded.pnm[3] = (cid[NDXC] >> 8) & 0xff; + decoded.pnm[4] = cid[NDXC] & 0xff; decoded.pnm[5] = '\0'; /* Word 3: Bits 32-63 @@ -879,8 +893,8 @@ static void mmcsd_decodeCID(FAR struct mmcsd_state_s *priv, uint32_t cid[4]) * psn - 55-24 32-bit Product serial number */ - decoded.prv = cid[1] >> 24; - decoded.psn = cid[1] << 8; + decoded.prv = cid[NDXB] >> 24; + decoded.psn = cid[NDXB] << 8; /* Word 4: Bits 0-31 * psn - 55-24 32-bit Product serial number @@ -889,9 +903,9 @@ static void mmcsd_decodeCID(FAR struct mmcsd_state_s *priv, uint32_t cid[4]) * crc - 7:1 7-bit CRC7 */ - decoded.psn |= cid[0] >> 24; - decoded.mdt = (cid[0] >> 8) & 0x0fff; - decoded.crc = (cid[0] >> 1) & 0x7f; + decoded.psn |= cid[NDXA] >> 24; + decoded.mdt = (cid[NDXA] >> 8) & 0x0fff; + decoded.crc = (cid[NDXA] >> 1) & 0x7f; finfo("mid: %02x oid: %04x pnm: %s prv: %d psn: %lu mdt: %02x crc: %02x\n", decoded.mid, decoded.oid, decoded.pnm, decoded.prv, @@ -924,26 +938,26 @@ struct mmcsd_scr_s decoded; */ #ifdef CONFIG_ENDIAN_BIG /* Card transfers SCR in big-endian order */ - priv->buswidth = (scr[0] >> 16) & 15; + priv->buswidth = (scr[NDXA] >> 16) & 15; #else - priv->buswidth = (scr[0] >> 8) & 15; + priv->buswidth = (scr[NDXA] >> 8) & 15; #endif #ifdef CONFIG_DEBUG_FS_INFO #ifdef CONFIG_ENDIAN_BIG /* Card SCR is big-endian order / CPU also big-endian * 60 56 52 48 44 40 36 32 * VVVV SSSS ESSS BBBB RRRR RRRR RRRR RRRR */ - decoded.scrversion = scr[0] >> 28; - decoded.sdversion = (scr[0] >> 24) & 15; - decoded.erasestate = (scr[0] >> 23) & 1; - decoded.security = (scr[0] >> 20) & 7; + decoded.scrversion = scr[NDXA] >> 28; + decoded.sdversion = (scr[NDXA] >> 24) & 15; + decoded.erasestate = (scr[NDXA] >> 23) & 1; + decoded.security = (scr[NDXA] >> 20) & 7; #else /* Card SCR is big-endian order / CPU is little-endian * 36 32 44 40 52 48 60 56 * RRRR RRRR RRRR RRRR ESSS BBBB VVVV SSSS */ - decoded.scrversion = (scr[0] >> 4) & 15; - decoded.sdversion = scr[0] & 15; - decoded.erasestate = (scr[0] >> 15) & 1; - decoded.security = (scr[0] >> 12) & 7; + decoded.scrversion = (scr[NDXA] >> 4) & 15; + decoded.sdversion = scr[NDXA] & 15; + decoded.erasestate = (scr[NDXA] >> 15) & 1; + decoded.security = (scr[NDXA] >> 12) & 7; #endif decoded.buswidth = priv->buswidth; #endif @@ -953,7 +967,7 @@ struct mmcsd_scr_s decoded; */ #ifdef CONFIG_DEBUG_FS_INFO - decoded.mfgdata = scr[1]; /* Might be byte reversed! */ + decoded.mfgdata = scr[NDXB]; /* Might be byte reversed! */ finfo("SCR:\n"); finfo(" SCR_STRUCTURE: %d SD_VERSION: %d\n",