summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-08-10 18:29:22 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-08-10 18:29:22 -0600
commit9a16be559048f93c3396183b1dc1261781d54b01 (patch)
tree4c78c20cc9d421394a718b1fa6b81fbeaec50adf /nuttx
parent11719aa69e37addcdd96215953844966c32149d7 (diff)
downloadnuttx-9a16be559048f93c3396183b1dc1261781d54b01.tar.gz
nuttx-9a16be559048f93c3396183b1dc1261781d54b01.tar.bz2
nuttx-9a16be559048f93c3396183b1dc1261781d54b01.zip
MMC/SD SDIO: Correct return values when multiple block transfers are suppressed. From Andrew Tridgell via Lorenz Meier
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/ChangeLog4
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_sdio.c78
2 files changed, 50 insertions, 32 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index a08d71418..691f3dcc3 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -5339,3 +5339,7 @@
functional on the SAMA5 with DMA! (2013-8-10).
* arch/arm/src/sam34/sam3u_periphclks.h: Correct a typo in a register
name (2013-8-10).
+ * drivers/mmcsd/mmcsd_sdio.c: Correction for a bad return value
+ when multiple block SDIO transfers are suppressed. By Andrew Tridgell
+ via Lorenz Meier (2013-8-10).
+
diff --git a/nuttx/drivers/mmcsd/mmcsd_sdio.c b/nuttx/drivers/mmcsd/mmcsd_sdio.c
index b265fab4a..4d39e847a 100644
--- a/nuttx/drivers/mmcsd/mmcsd_sdio.c
+++ b/nuttx/drivers/mmcsd/mmcsd_sdio.c
@@ -1,7 +1,7 @@
/****************************************************************************
* drivers/mmcsd/mmcsd_sdio.c
*
- * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2009-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -293,7 +293,7 @@ static void mmcsd_takesem(FAR struct mmcsd_state_s *priv)
/* Lock the bus if mutually exclusive access to the SDIO bus is required
* on this platform.
*/
-
+
#ifdef CONFIG_SDIO_MUXBUS
SDIO_LOCK(priv->dev, TRUE);
#endif
@@ -607,7 +607,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
#endif
/* Word 3: Bits 32-63
- *
+ *
* Byte addressed SD:
* C_SIZE 73:62 Device size
* VDD_R_CURR_MIN 61:59 Max. read current at Vcc min
@@ -659,7 +659,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
priv->nblocks = priv->capacity >> 9;
#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
- decoded.u.sdblock.csize = csize;
+ decoded.u.sdblock.csize = csize;
decoded.u.sdblock.sderblen = (csd[2] >> 14) & 1;
decoded.u.sdblock.sdsectorsize = (csd[2] >> 7) & 0x7f;
decoded.u.sdblock.sdwpgrpsize = csd[2] & 0x7f;
@@ -697,7 +697,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
if (IS_SD(priv->type))
{
- decoded.u.sdbyte.csize = csize;
+ decoded.u.sdbyte.csize = csize;
decoded.u.sdbyte.vddrcurrmin = (csd[2] >> 27) & 7;
decoded.u.sdbyte.vddrcurrmax = (csd[2] >> 24) & 7;
decoded.u.sdbyte.vddwcurrmin = (csd[2] >> 21) & 7;
@@ -710,7 +710,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
#ifdef CONFIG_MMCSD_MMCSUPPORT
else if (IS_MMC(priv->type))
{
- decoded.u.mmc.csize = csize;
+ decoded.u.mmc.csize = csize;
decoded.u.mmc.vddrcurrmin = (csd[2] >> 27) & 7;
decoded.u.mmc.vddrcurrmax = (csd[2] >> 24) & 7;
decoded.u.mmc.vddwcurrmin = (csd[2] >> 21) & 7;
@@ -737,7 +737,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
* FILE_FORMAT 10:11 File format
* ECC 9:8 ECC (MMC only)
* CRC 7:1 CRC
- * Not used 0:0
+ * Not used 0:0
*/
permwriteprotect = (csd[3] >> 13) & 1;
@@ -757,7 +757,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
decoded.fileformat = (csd[3] >> 10) & 3;
decoded.mmcecc = (csd[3] >> 8) & 3;
decoded.crc = (csd[3] >> 1) & 0x7f;
-
+
fvdbg("CSD:\n");
fvdbg(" CSD_STRUCTURE: %d SPEC_VERS: %d (MMC)\n",
decoded.csdstructure, decoded.mmcspecvers);
@@ -1043,7 +1043,7 @@ static int mmcsd_verifystate(FAR struct mmcsd_state_s *priv, uint32_t state)
*
* Description:
* Return true if the the card is unlocked an not write protected. The
- *
+ *
*
****************************************************************************/
@@ -1501,13 +1501,16 @@ static ssize_t mmcsd_reload(FAR void *dev, FAR uint8_t *buffer,
/* Read each block using only the single block transfer method */
endblock = startblock + nblocks - 1;
+ ret = nblocks;
+
for (block = startblock; block <= endblock; block++)
{
/* Read this block into the user buffer */
- ret = mmcsd_readsingle(priv, buffer, block);
- if (ret < 0)
+ ssize_t nread = mmcsd_readsingle(priv, buffer, block);
+ if (nread < 0)
{
+ ret = nread;
break;
}
@@ -1515,6 +1518,7 @@ static ssize_t mmcsd_reload(FAR void *dev, FAR uint8_t *buffer,
buffer += priv->blocksize;
}
+
#else
/* Use either the single- or muliple-block transfer method */
@@ -1526,6 +1530,7 @@ static ssize_t mmcsd_reload(FAR void *dev, FAR uint8_t *buffer,
{
ret = mmcsd_readmultiple(priv, buffer, startblock, nblocks);
}
+
#endif
/* On success, return the number of blocks read */
@@ -1816,7 +1821,7 @@ static ssize_t mmcsd_flush(FAR void *dev, FAR const uint8_t *buffer,
size_t block;
size_t endblock;
#endif
- ssize_t ret;
+ ssize_t ret = nblocks;
DEBUGASSERT(priv != NULL && buffer != NULL && nblocks > 0)
@@ -1828,9 +1833,10 @@ static ssize_t mmcsd_flush(FAR void *dev, FAR const uint8_t *buffer,
{
/* Write this block from the user buffer */
- ret = mmcsd_writesingle(priv, buffer, block);
- if (ret < 0)
+ ssize_t nread = mmcsd_writesingle(priv, buffer, block);
+ if (nread < 0)
{
+ ret = nread;
break;
}
@@ -1838,6 +1844,7 @@ static ssize_t mmcsd_flush(FAR void *dev, FAR const uint8_t *buffer,
buffer += priv->blocksize;
}
+
#else
if (nblocks == 1)
{
@@ -1847,6 +1854,7 @@ static ssize_t mmcsd_flush(FAR void *dev, FAR const uint8_t *buffer,
{
ret = mmcsd_writemultiple(priv, buffer, startblock, nblocks);
}
+
#endif
/* On success, return the number of blocks written */
@@ -1923,7 +1931,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
size_t sector;
size_t endsector;
#endif
- ssize_t ret = 0;
+ ssize_t ret = nsectors;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct mmcsd_state_s *)inode->i_private;
@@ -1947,9 +1955,10 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
{
/* Read this sector into the user buffer */
- ret = mmcsd_readsingle(priv, buffer, sector);
- if (ret < 0)
+ ssize_t nread = mmcsd_readsingle(priv, buffer, sector);
+ if (nread < 0)
{
+ ret = nread;
break;
}
@@ -1957,6 +1966,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
buffer += priv->blocksize;
}
+
#else
/* Use either the single- or muliple-block transfer method */
@@ -1968,6 +1978,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
{
ret = mmcsd_readmultiple(priv, buffer, startsector, nsectors);
}
+
#endif
mmcsd_givesem(priv);
}
@@ -1995,7 +2006,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, FAR const unsigned char *buf
size_t sector;
size_t endsector;
#endif
- ssize_t ret = 0;
+ ssize_t ret = nsectors;
fvdbg("sector: %d nsectors: %d sectorsize: %d\n");
DEBUGASSERT(inode && inode->i_private);
@@ -2016,9 +2027,10 @@ static ssize_t mmcsd_write(FAR struct inode *inode, FAR const unsigned char *buf
{
/* Write this block from the user buffer */
- ret = mmcsd_writesingle(priv, buffer, sector);
- if (ret < 0)
+ ssize_t nread = mmcsd_writesingle(priv, buffer, sector);
+ if (nread < 0)
{
+ ret = nread;
break;
}
@@ -2026,6 +2038,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, FAR const unsigned char *buf
buffer += priv->blocksize;
}
+
#else
/* Use either the single- or multiple-block transfer method */
@@ -2037,6 +2050,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, FAR const unsigned char *buf
{
ret = mmcsd_writemultiple(priv, buffer, startsector, nsectors);
}
+
#endif
mmcsd_givesem(priv);
@@ -2149,7 +2163,7 @@ static int mmcsd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
{
fdbg("ERROR: mmcsd_removed failed: %d\n", ret);
}
-
+
/* Enable logic to detect if a card is re-inserted */
SDIO_CALLBACKENABLE(priv->dev, SDIOMEDIA_INSERTED);
@@ -2175,7 +2189,7 @@ static int mmcsd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
* Description:
* This is a callback function from the SDIO driver that indicates that
* there has been a change in the slot... either a card has been inserted
- * or a card has been removed.
+ * or a card has been removed.
*
* Assumptions:
* This callback is NOT supposd to run in the context of an interrupt
@@ -2191,7 +2205,7 @@ static void mmcsd_mediachange(FAR void *arg)
DEBUGASSERT(priv);
/* Is there a card present in the slot? */
-
+
mmcsd_takesem(priv);
if (SDIO_PRESENT(priv->dev))
{
@@ -2304,12 +2318,12 @@ static int mmcsd_widebus(FAR struct mmcsd_state_s *priv)
fdbg("WARNING: Card does not support wide-bus operation\n");
return -ENOSYS;
-
+
#else /* CONFIG_SDIO_WIDTH_D1_ONLY */
fvdbg("Wide-bus operation is disabled\n");
return -ENOSYS;
-
+
#endif /* CONFIG_SDIO_WIDTH_D1_ONLY */
}
@@ -2365,7 +2379,7 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv)
}
/* This should have caused a transition to standby state. However, this will
- * not be reflected in the present R1 status. R1/6 contains the state of the
+ * not be reflected in the present R1 status. R1/6 contains the state of the
* card when the command was received, not when it completed execution.
*
* Verify that we are in standby state/data-transfer mode
@@ -2453,7 +2467,7 @@ static int mmcsd_sdinitialize(FAR struct mmcsd_state_s *priv)
* to assign a logical address to the card. For MMC, the host assigns the
* address; for SD, the memory card has this responsibility. CMD3 causes
* transition to standby state/data-transfer mode
- *
+ *
* Send CMD3 with argument 0, SD card publishes its RCA in the response.
*/
@@ -2467,7 +2481,7 @@ static int mmcsd_sdinitialize(FAR struct mmcsd_state_s *priv)
fvdbg("RCA: %04x\n", priv->rca);
/* This should have caused a transition to standby state. However, this will
- * not be reflected in the present R1 status. R1/6 contains the state of
+ * not be reflected in the present R1 status. R1/6 contains the state of
* the card when the command was received, not when it completed execution.
*
* Verify that we are in standby state/data-transfer mode
@@ -2836,7 +2850,7 @@ static int mmcsd_probe(FAR struct mmcsd_state_s *priv)
#endif
/* Otherwise, we are going to probe the card. There are lots of
- * possibilities here: We may think that there is a card in the slot,
+ * possibilities here: We may think that there is a card in the slot,
* or not. There may be a card in the slot, or not. If there is
* card in the slot, perhaps it is a different card than we one we
* think is there? The safest thing to do is to process the card
@@ -3000,8 +3014,8 @@ static int mmcsd_hwinitialize(FAR struct mmcsd_state_s *priv)
* 2. Electrical insertion that can be sensed using the pull-up resistor
* on CD/DAT3 (both SD/MMC),
* 3. Or by periodic attempts to initialize the card from software.
- *
- * The behavior of SDIO_PRESENT() is to use whatever information is available
+ *
+ * The behavior of SDIO_PRESENT() is to use whatever information is available
* on the particular platform. If no card insertion information is available
* (polling only), then SDIO_PRESENT() will always return true and we will
* try to initialize the card.
@@ -3128,7 +3142,7 @@ int mmcsd_slotinitialize(int minor, FAR struct sdio_dev_s *dev)
if (ret == -ENODEV)
{
/* No card in the slot (or if there is, we could not recognize
- * it).. Setup to receive the media inserted event
+ * it).. Setup to receive the media inserted event
*/
SDIO_CALLBACKENABLE(priv->dev, SDIOMEDIA_INSERTED);