nuttx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aguettou...@apache.org
Subject [incubator-nuttx] branch master updated: Check return from nxsem_wait_uninterruptible()
Date Sat, 04 Apr 2020 19:00:13 GMT
This is an automated email from the ASF dual-hosted git repository.

aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 1501d28  Check return from nxsem_wait_uninterruptible()
1501d28 is described below

commit 1501d284c33d073dbdac5767de1cb859ae27726d
Author: Gregory Nutt <gnutt@nuttx.org>
AuthorDate: Sat Apr 4 10:38:16 2020 -0600

    Check return from nxsem_wait_uninterruptible()
    
    Resolution of Issue 619 will require multiple steps, this part of the first step in that
resolution:  Every call to nxsem_wait_uninterruptible() must handle the return value from
nxsem_wait_uninterruptible properly.  This commit is for all SDIO card drivers under arch/.
---
 arch/arm/src/cxd56xx/cxd56_sdhci.c          | 84 ++++++++++++++++++++++-------
 arch/arm/src/imxrt/imxrt_usdhc.c            | 21 ++++++--
 arch/arm/src/kinetis/kinetis_sdhc.c         | 21 ++++++--
 arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c |  9 ++--
 arch/arm/src/lpc43xx/lpc43_sdmmc.c          | 22 ++++++--
 arch/arm/src/lpc54xx/lpc54_sdmmc.c          | 22 ++++++--
 arch/arm/src/sam34/sam_hsmci.c              | 23 ++++++--
 arch/arm/src/sama5/sam_hsmci.c              | 23 ++++++--
 arch/arm/src/samv7/sam_hsmci.c              | 23 ++++++--
 arch/arm/src/samv7/sam_twihs.c              | 23 +-------
 arch/arm/src/stm32/stm32_sdio.c             | 28 ++++++----
 arch/arm/src/stm32f7/stm32_sdmmc.c          | 28 ++++++----
 arch/arm/src/stm32h7/stm32_sdmmc.c          | 28 ++++++----
 arch/arm/src/stm32l4/stm32l4_sdmmc.c        | 28 ++++++----
 14 files changed, 268 insertions(+), 115 deletions(-)

diff --git a/arch/arm/src/cxd56xx/cxd56_sdhci.c b/arch/arm/src/cxd56xx/cxd56_sdhci.c
index 0af13e0..0028d8a 100644
--- a/arch/arm/src/cxd56xx/cxd56_sdhci.c
+++ b/arch/arm/src/cxd56xx/cxd56_sdhci.c
@@ -359,7 +359,7 @@ struct cxd56_sdhcregs_s
 
 /* Low-level helpers ********************************************************/
 
-static void cxd56_takesem(struct cxd56_sdiodev_s *priv);
+static int  cxd56_takesem(struct cxd56_sdiodev_s *priv);
 #define     cxd56_givesem(priv) (nxsem_post(&(priv)->waitsem))
 static void cxd56_configwaitints(struct cxd56_sdiodev_s *priv,
               uint32_t waitints, sdio_eventset_t waitevents,
@@ -566,13 +566,14 @@ static FAR uint32_t cxd56_sdhci_adma_dscr[CXD56_SDIO_MAX_LEN_ADMA_DSCR
* 2];
  *   dev - Instance of the SDIO device driver state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void cxd56_takesem(struct cxd56_sdiodev_s *priv)
+static int cxd56_takesem(struct cxd56_sdiodev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2664,7 +2665,17 @@ static sdio_eventset_t cxd56_sdio_eventwait(FAR struct sdio_dev_s *dev,
        * there will be no wait.
        */
 
-      cxd56_takesem(priv);
+      ret = cxd56_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started) and
+           * return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          return SDIOWAIT_ERROR;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred
@@ -3233,9 +3244,9 @@ static void cxd56_sdio_callback(void *arg)
 }
 
 #ifdef CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION
-static void cxd56_sdio_takesem(FAR struct cxd56_sdiodev_s *priv)
+static int cxd56_sdio_takesem(FAR struct cxd56_sdiodev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->sc.sem);
+  return nxsem_wait_uninterruptible(&priv->sc.sem);
 }
 
 /****************************************************************************
@@ -3732,7 +3743,11 @@ static int cxd56_sdio_register_irq(FAR struct sdio_dev_s *dev, int
func_num,
       return -EBUSY;
     }
 
-  cxd56_sdio_takesem(priv);
+  ret = cxd56_sdio_takesem(priv);
+  if (ret < 0)
+    {
+      return ret;
+    }
 
   /* enable irq in device side */
 
@@ -3849,7 +3864,12 @@ static int cxd56_sdio_function_disable(FAR struct sdio_dev_s *dev,
   sf0 = priv->sc.fn[0];
   mcinfo("I/O func's num:%d\n", sf->number);
 
-  cxd56_sdio_takesem(priv);
+  ret = cxd56_sdio_takesem(priv);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
   ret = cxd56_sdio_readb_internal(sf0, SDIO_CCCR_IOEN, &rv);
   if (ret)
     {
@@ -3865,6 +3885,7 @@ static int cxd56_sdio_function_disable(FAR struct sdio_dev_s *dev,
 
   nxsem_post(&priv->sc.sem);
   return 0;
+
 FUNC_DIS_ERR:
   mcerr("ERROR: Io fail ret %u\n", ret);
   nxsem_post(&priv->sc.sem);
@@ -3901,7 +3922,12 @@ static int cxd56_sdio_function_enable(FAR struct sdio_dev_s *dev,
       return 0;
     }
 
-  cxd56_sdio_takesem(priv);
+  ret = cxd56_sdio_takesem(priv);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
   ret = cxd56_sdio_readb_internal(sf0, SDIO_CCCR_IOEN, &rv);
   if (ret)
     {
@@ -3962,9 +3988,13 @@ static int cxd56_sdio_readb(FAR struct sdio_dev_s *dev, int func_num,
   struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
   int ret;
 
-  cxd56_sdio_takesem(priv);
-  ret = cxd56_sdio_readb_internal(priv->sc.fn[func_num], addr, rdata);
-  nxsem_post(&priv->sc.sem);
+  ret = cxd56_sdio_takesem(priv);
+  if (ret >= 0)
+    {
+      ret = cxd56_sdio_readb_internal(priv->sc.fn[func_num], addr, rdata);
+      nxsem_post(&priv->sc.sem);
+    }
+
   return ret;
 }
 
@@ -3991,9 +4021,14 @@ static int cxd56_sdio_writeb(FAR struct sdio_dev_s *dev, int func_num,
   struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
   int ret;
 
-  cxd56_sdio_takesem(priv);
-  ret = cxd56_sdio_writeb_internal(priv->sc.fn[func_num], addr, data, rdata);
-  nxsem_post(&priv->sc.sem);
+  ret = cxd56_sdio_takesem(priv);
+  if (ret >= 0)
+    {
+      ret = cxd56_sdio_writeb_internal(priv->sc.fn[func_num], addr, data,
+                                       data);
+      nxsem_post(&priv->sc.sem);
+    }
+
   return ret;
 }
 
@@ -4014,7 +4049,8 @@ static int cxd56_sdio_writeb(FAR struct sdio_dev_s *dev, int func_num,
  ****************************************************************************/
 
 static int cxd56_sdio_write(FAR struct sdio_dev_s *dev, int func_num,
-                    uint32_t addr, FAR uint8_t * data, uint32_t size)
+                            uint32_t addr, FAR uint8_t * data,
+                            uint32_t size)
 {
   uint32_t remainder = size;
   int ret;
@@ -4028,7 +4064,12 @@ static int cxd56_sdio_write(FAR struct sdio_dev_s *dev, int func_num,
 
   /* Do the bulk of the transfer using block mode (if supported). */
 
-  cxd56_sdio_takesem(priv);
+  ret = cxd56_sdio_takesem(priv);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
   if (size >= SDIO_BLOCK_SIZE)
     {
       while (remainder >= SDIO_BLOCK_SIZE)
@@ -4165,7 +4206,12 @@ static int cxd56_sdio_read(FAR struct sdio_dev_s *dev, int func_num,
 
   /* Do the bulk of the transfer using block mode (if supported). */
 
-  cxd56_sdio_takesem(priv);
+  ret = cxd56_sdio_takesem(priv);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
   if (size >= SDIO_BLOCK_SIZE)
     {
       while (remainder >= SDIO_BLOCK_SIZE)
diff --git a/arch/arm/src/imxrt/imxrt_usdhc.c b/arch/arm/src/imxrt/imxrt_usdhc.c
index e582455..40b4b6e 100644
--- a/arch/arm/src/imxrt/imxrt_usdhc.c
+++ b/arch/arm/src/imxrt/imxrt_usdhc.c
@@ -254,7 +254,7 @@ struct imxrt_sdhcregs_s
 
 /* Low-level helpers ********************************************************/
 
-static void imxrt_takesem(struct imxrt_dev_s *priv);
+static int  imxrt_takesem(struct imxrt_dev_s *priv);
 #define     imxrt_givesem(priv) (nxsem_post(&priv->waitsem))
 static void imxrt_configwaitints(struct imxrt_dev_s *priv, uint32_t waitints,
               sdio_eventset_t waitevents, sdio_eventset_t wkupevents);
@@ -514,13 +514,14 @@ static struct imxrt_sdhcregs_s g_sampleregs[DEBUG_NSAMPLES];
  *   dev - Instance of the SDIO device driver state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void imxrt_takesem(struct imxrt_dev_s *priv)
+static int imxrt_takesem(struct imxrt_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2724,7 +2725,17 @@ static sdio_eventset_t imxrt_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      imxrt_takesem(priv);
+      ret = imxrt_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started) and
+           * return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          return SDIOWAIT_ERROR;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
diff --git a/arch/arm/src/kinetis/kinetis_sdhc.c b/arch/arm/src/kinetis/kinetis_sdhc.c
index a360cb1..e3fb7c1 100644
--- a/arch/arm/src/kinetis/kinetis_sdhc.c
+++ b/arch/arm/src/kinetis/kinetis_sdhc.c
@@ -229,7 +229,7 @@ struct kinetis_sdhcregs_s
 
 /* Low-level helpers ********************************************************/
 
-static void kinetis_takesem(struct kinetis_dev_s *priv);
+static int  kinetis_takesem(struct kinetis_dev_s *priv);
 #define     kinetis_givesem(priv) (nxsem_post(&priv->waitsem))
 static void kinetis_configwaitints(struct kinetis_dev_s *priv,
               uint32_t waitints, sdio_eventset_t waitevents,
@@ -423,13 +423,14 @@ static struct kinetis_sdhcregs_s g_sampleregs[DEBUG_NSAMPLES];
  *   dev - Instance of the SDIO device driver state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void kinetis_takesem(struct kinetis_dev_s *priv)
+static int kinetis_takesem(struct kinetis_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2520,7 +2521,17 @@ static sdio_eventset_t kinetis_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      kinetis_takesem(priv);
+      ret = kinetis_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started) and
+           * return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          return SDIOWAIT_ERROR;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
diff --git a/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c b/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c
index 36b381a..e3d5f08 100644
--- a/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c
+++ b/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c
@@ -488,7 +488,8 @@ static struct lpc17_40_sampleregs_s g_sampleregs[DEBUG_NSAMPLES];
  *   dev - Instance of the SD card device driver state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
@@ -2363,10 +2364,12 @@ static sdio_eventset_t lpc17_40_eventwait(FAR struct sdio_dev_s *dev,
       ret = lpc17_40_takesem(priv);
       if (ret < 0)
         {
-          wd_cancel(priv->waitwdog);
+          /* Task canceled.  Cancel the wdog (assuming it was started) and
+           * return an SDIO error.
+           */
 
+          wd_cancel(priv->waitwdog);
           leave_critical_section(flags);
-
           return SDIOWAIT_ERROR;
         }
 
diff --git a/arch/arm/src/lpc43xx/lpc43_sdmmc.c b/arch/arm/src/lpc43xx/lpc43_sdmmc.c
index a41106a..b5e93ae5029 100644
--- a/arch/arm/src/lpc43xx/lpc43_sdmmc.c
+++ b/arch/arm/src/lpc43xx/lpc43_sdmmc.c
@@ -271,7 +271,7 @@ static void lpc43_putreg(uint32_t val, uint32_t addr);
 
 /* Low-level helpers ********************************************************/
 
-static void lpc43_takesem(struct lpc43_dev_s *priv);
+static int  lpc43_takesem(struct lpc43_dev_s *priv);
 #define     lpc43_givesem(priv) (nxsem_post(&priv->waitsem))
 static inline void lpc43_setclock(uint32_t clkdiv);
 static inline void lpc43_sdcard_clock(bool enable);
@@ -525,13 +525,14 @@ static void lpc43_putreg(uint32_t val, uint32_t addr)
  *   dev - Instance of the SD card device driver state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void lpc43_takesem(struct lpc43_dev_s *priv)
+static int lpc43_takesem(struct lpc43_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2329,7 +2330,18 @@ static sdio_eventset_t lpc43_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      lpc43_takesem(priv);
+      ret = lpc43_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog -- assuming it was started and
+           * return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          leave_critical_section(flags);
+          return SDIOWAIT_ERROR;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
diff --git a/arch/arm/src/lpc54xx/lpc54_sdmmc.c b/arch/arm/src/lpc54xx/lpc54_sdmmc.c
index be8c0d2..c9878a3 100644
--- a/arch/arm/src/lpc54xx/lpc54_sdmmc.c
+++ b/arch/arm/src/lpc54xx/lpc54_sdmmc.c
@@ -275,7 +275,7 @@ static void lpc54_putreg(uint32_t val, uint32_t addr);
 
 /* Low-level helpers ********************************************************/
 
-static void lpc54_takesem(struct lpc54_dev_s *priv);
+static int  lpc54_takesem(struct lpc54_dev_s *priv);
 #define     lpc54_givesem(priv) (nxsem_post(&priv->waitsem))
 static inline void lpc54_setclock(uint32_t clkdiv);
 static inline void lpc54_sdcard_clock(bool enable);
@@ -529,13 +529,14 @@ static void lpc54_putreg(uint32_t val, uint32_t addr)
  *   dev - Instance of the SD card device driver state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void lpc54_takesem(struct lpc54_dev_s *priv)
+static int lpc54_takesem(struct lpc54_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2329,7 +2330,18 @@ static sdio_eventset_t lpc54_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      lpc54_takesem(priv);
+      ret = lpc54_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started) and
+           * return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          leave_critical_section(flags);
+          return SDIOWAIT_ERROR;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
diff --git a/arch/arm/src/sam34/sam_hsmci.c b/arch/arm/src/sam34/sam_hsmci.c
index 5324a45..851fb81 100644
--- a/arch/arm/src/sam34/sam_hsmci.c
+++ b/arch/arm/src/sam34/sam_hsmci.c
@@ -394,7 +394,7 @@ struct sam_xfrregs_s
 
 /* Low-level helpers ********************************************************/
 
-static void sam_takesem(struct sam_dev_s *priv);
+static int  sam_takesem(struct sam_dev_s *priv);
 #define     sam_givesem(priv) (nxsem_post(&priv->waitsem))
 
 static void sam_configwaitints(struct sam_dev_s *priv, uint32_t waitmask,
@@ -575,13 +575,14 @@ static bool                     g_cmdinitialized;
  *   dev - Instance of the SDIO device driver state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void sam_takesem(struct sam_dev_s *priv)
+static int sam_takesem(struct sam_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2342,7 +2343,19 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      sam_takesem(priv);
+      ret = sam_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started),
+           * disable all event, and return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          sam_disablexfrints(priv);
+          sam_disablewaitints(priv, SDIOWAIT_ERROR);
+          return SDIOWAIT_ERROR;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
diff --git a/arch/arm/src/sama5/sam_hsmci.c b/arch/arm/src/sama5/sam_hsmci.c
index a226b18..bb4c807 100644
--- a/arch/arm/src/sama5/sam_hsmci.c
+++ b/arch/arm/src/sama5/sam_hsmci.c
@@ -458,7 +458,7 @@ struct sam_dev_s
 
 /* Low-level helpers ********************************************************/
 
-static void sam_takesem(struct sam_dev_s *priv);
+static int  sam_takesem(struct sam_dev_s *priv);
 #define     sam_givesem(priv) (nxsem_post(&priv->waitsem))
 
 #ifdef CONFIG_SAMA5_HSMCI_REGDEBUG
@@ -668,13 +668,14 @@ static struct sam_dev_s g_hsmci2;
  *   dev - Instance of the SDIO device driver state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void sam_takesem(struct sam_dev_s *priv)
+static int sam_takesem(struct sam_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2763,7 +2764,19 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      sam_takesem(priv);
+      ret = sam_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started),
+           * disable all event, and return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          sam_disablexfrints(priv);
+          sam_disablewaitints(priv, SDIOWAIT_ERROR);
+          return SDIOWAIT_ERROR;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
diff --git a/arch/arm/src/samv7/sam_hsmci.c b/arch/arm/src/samv7/sam_hsmci.c
index ece88b4..82e7905 100644
--- a/arch/arm/src/samv7/sam_hsmci.c
+++ b/arch/arm/src/samv7/sam_hsmci.c
@@ -393,7 +393,7 @@ struct sam_dev_s
 
 /* Low-level helpers ********************************************************/
 
-static void sam_takesem(struct sam_dev_s *priv);
+static int  sam_takesem(struct sam_dev_s *priv);
 #define     sam_givesem(priv) (nxsem_post(&priv->waitsem))
 
 #ifdef CONFIG_SAMV7_HSMCI_REGDEBUG
@@ -600,13 +600,14 @@ static struct sam_dev_s g_hsmci1;
  *   dev - Instance of the SDIO device driver state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void sam_takesem(struct sam_dev_s *priv)
+static int sam_takesem(struct sam_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2811,7 +2812,19 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      sam_takesem(priv);
+      ret = sam_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started),
+           * disable all event, and return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          sam_disablexfrints(priv);
+          sam_disablewaitints(priv, SDIOWAIT_ERROR);
+          return SDIOWAIT_ERROR;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
diff --git a/arch/arm/src/samv7/sam_twihs.c b/arch/arm/src/samv7/sam_twihs.c
index 9d75440..0d778e6 100644
--- a/arch/arm/src/samv7/sam_twihs.c
+++ b/arch/arm/src/samv7/sam_twihs.c
@@ -181,7 +181,6 @@ struct twi_dev_s
 /* Low-level helper functions */
 
 static int  twi_takesem(sem_t *sem);
-static int  twi_takesem_uninterruptible(sem_t *sem);
 #define     twi_givesem(sem) (nxsem_post(sem))
 
 #ifdef CONFIG_SAMV7_TWIHSHS_REGDEBUG
@@ -322,26 +321,6 @@ static int twi_takesem(sem_t *sem)
 }
 
 /****************************************************************************
- * Name: twi_takesem_uninterruptible
- *
- * Description:
- *   Take the wait semaphore (handling false alarm wake-ups due to the
- *   receipt of signals).
- *
- * Input Parameters:
- *   dev - Instance of the SDIO device driver state structure.
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-static int twi_takesem_uninterruptible(sem_t *sem)
-{
-  return nxsem_wait_uninterruptible(sem);
-}
-
-/****************************************************************************
  * Name: twi_checkreg
  *
  * Description:
@@ -1156,7 +1135,7 @@ static int twi_reset(FAR struct i2c_master_s *dev)
 
   /* Get exclusive access to the TWIHS device */
 
-  ret = twi_takesem_uninterruptible(&priv->exclsem);
+  ret = twi_takesem(&priv->exclsem);
   if (ret >= 0)
     {
       /* Do the reset-procedure */
diff --git a/arch/arm/src/stm32/stm32_sdio.c b/arch/arm/src/stm32/stm32_sdio.c
index ec1f001..1cf001b 100644
--- a/arch/arm/src/stm32/stm32_sdio.c
+++ b/arch/arm/src/stm32/stm32_sdio.c
@@ -379,7 +379,7 @@ struct stm32_sampleregs_s
 
 /* Low-level helpers ********************************************************/
 
-static void stm32_takesem(struct stm32_dev_s *priv);
+static int  stm32_takesem(struct stm32_dev_s *priv);
 #define     stm32_givesem(priv) (nxsem_post(&priv->waitsem))
 static inline void stm32_setclkcr(uint32_t clkcr);
 static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask,
@@ -573,13 +573,14 @@ static struct stm32_sampleregs_s g_sampleregs[DEBUG_NSAMPLES];
  *   dev - Instance of the SDIO device driver state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void stm32_takesem(struct stm32_dev_s *priv)
+static int stm32_takesem(struct stm32_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2512,7 +2513,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
   if (priv->waitevents == 0 && priv->wkupevent == 0)
     {
       wkupevent = SDIOWAIT_ERROR;
-      goto erroutdisable;
+      goto errout_with_waitints;
     }
 
 #else
@@ -2576,7 +2577,18 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      stm32_takesem(priv);
+      ret = stm32_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started) and
+           * return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          wkupevent = SDIOWAIT_ERROR;
+          goto errout_with_waitints;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
@@ -2594,9 +2606,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
 
   /* Disable event-related interrupts */
 
-#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE)
-erroutdisable:
-#endif
+errout_with_waitints:
 
   stm32_configwaitints(priv, 0, 0, 0);
 #ifdef CONFIG_STM32_SDIO_DMA
diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c
index e2a1458..34870f7 100644
--- a/arch/arm/src/stm32f7/stm32_sdmmc.c
+++ b/arch/arm/src/stm32f7/stm32_sdmmc.c
@@ -471,7 +471,7 @@ struct stm32_sampleregs_s
 static inline void sdmmc_putreg32(struct stm32_dev_s *priv, uint32_t value,
               int offset);
 static inline uint32_t sdmmc_getreg32(struct stm32_dev_s *priv, int offset);
-static void stm32_takesem(struct stm32_dev_s *priv);
+static int  stm32_takesem(struct stm32_dev_s *priv);
 #define     stm32_givesem(priv) (nxsem_post(&priv->waitsem))
 static inline void stm32_setclkcr(struct stm32_dev_s *priv, uint32_t clkcr);
 static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask,
@@ -786,13 +786,14 @@ static inline void sdmmc_modifyreg32(struct stm32_dev_s *priv, int offset,
  *   priv  - Instance of the SDMMC private state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void stm32_takesem(struct stm32_dev_s *priv)
+static int stm32_takesem(struct stm32_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2794,7 +2795,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
   if (priv->waitevents == 0 && priv->wkupevent == 0)
     {
       wkupevent = SDIOWAIT_ERROR;
-      goto erroutdisable;
+      goto errout_with_waitints;
     }
 
 #else
@@ -2858,7 +2859,18 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      stm32_takesem(priv);
+      ret = stm32_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started) and
+           * return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          wkupevent = SDIOWAIT_ERROR;
+          goto errout_with_waitints;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
@@ -2876,9 +2888,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
 
   /* Disable event-related interrupts */
 
-#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE)
-erroutdisable:
-#endif
+errout_with_waitints:
 
   stm32_configwaitints(priv, 0, 0, 0);
 #ifdef CONFIG_STM32F7_SDMMC_DMA
diff --git a/arch/arm/src/stm32h7/stm32_sdmmc.c b/arch/arm/src/stm32h7/stm32_sdmmc.c
index f5c329c..f692771 100644
--- a/arch/arm/src/stm32h7/stm32_sdmmc.c
+++ b/arch/arm/src/stm32h7/stm32_sdmmc.c
@@ -392,7 +392,7 @@ struct stm32_sampleregs_s
 static inline void sdmmc_putreg32(struct stm32_dev_s *priv, uint32_t value,
                                   int offset);
 static inline uint32_t sdmmc_getreg32(struct stm32_dev_s *priv, int offset);
-static void stm32_takesem(struct stm32_dev_s *priv);
+static int  stm32_takesem(struct stm32_dev_s *priv);
 #define     stm32_givesem(priv) (nxsem_post(&priv->waitsem))
 static inline void stm32_setclkcr(struct stm32_dev_s *priv, uint32_t clkcr);
 static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask,
@@ -679,13 +679,14 @@ static inline void sdmmc_modifyreg32(struct stm32_dev_s *priv, int offset,
  *   priv  - Instance of the SDMMC private state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void stm32_takesem(struct stm32_dev_s *priv)
+static int stm32_takesem(struct stm32_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2698,7 +2699,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
   if (priv->waitevents == 0 && priv->wkupevent == 0)
     {
       wkupevent = SDIOWAIT_ERROR;
-      goto erroutdisable;
+      goto errout_with_waitints;
     }
 
 #else
@@ -2762,7 +2763,18 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      stm32_takesem(priv);
+      ret = stm32_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started) and
+           * return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          wkupevent = SDIOWAIT_ERROR;
+          goto errout_with_waitints;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
@@ -2780,9 +2792,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
 
   /* Disable event-related interrupts */
 
-#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE)
-erroutdisable:
-#endif
+errout_with_waitints:
 
   stm32_configwaitints(priv, 0, 0, 0);
 
diff --git a/arch/arm/src/stm32l4/stm32l4_sdmmc.c b/arch/arm/src/stm32l4/stm32l4_sdmmc.c
index 5d75f93..a4ef5c4 100644
--- a/arch/arm/src/stm32l4/stm32l4_sdmmc.c
+++ b/arch/arm/src/stm32l4/stm32l4_sdmmc.c
@@ -408,7 +408,7 @@ struct stm32_sampleregs_s
 static inline void sdmmc_putreg32(struct stm32_dev_s *priv, uint32_t value,
                                   int offset);
 static inline uint32_t sdmmc_getreg32(struct stm32_dev_s *priv, int offset);
-static void stm32_takesem(struct stm32_dev_s *priv);
+static int  stm32_takesem(struct stm32_dev_s *priv);
 #define     stm32_givesem(priv) (nxsem_post(&priv->waitsem))
 static inline void stm32_setclkcr(struct stm32_dev_s *priv, uint32_t clkcr);
 static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask,
@@ -703,13 +703,14 @@ static inline void sdmmc_modifyreg32(struct stm32_dev_s *priv, int offset,
  *   priv  - Instance of the SDMMC private state structure.
  *
  * Returned Value:
- *   None
+ *   Normally OK, but may return -ECANCELED in the rare event that the task
+ *   has been canceled.
  *
  ****************************************************************************/
 
-static void stm32_takesem(struct stm32_dev_s *priv)
+static int stm32_takesem(struct stm32_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 }
 
 /****************************************************************************
@@ -2600,7 +2601,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
   if (priv->waitevents == 0 && priv->wkupevent == 0)
     {
       wkupevent = SDIOWAIT_ERROR;
-      goto erroutdisable;
+      goto errout_with_waitints;
     }
 
 #else
@@ -2664,7 +2665,18 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
        * incremented and there will be no wait.
        */
 
-      stm32_takesem(priv);
+      ret = stm32_takesem(priv);
+      if (ret < 0)
+        {
+          /* Task canceled.  Cancel the wdog (assuming it was started) and
+           * return an SDIO error.
+           */
+
+          wd_cancel(priv->waitwdog);
+          wkupevent = SDIOWAIT_ERROR;
+          goto errout_with_waitints;
+        }
+
       wkupevent = priv->wkupevent;
 
       /* Check if the event has occurred.  When the event has occurred, then
@@ -2682,9 +2694,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
 
   /* Disable event-related interrupts */
 
-#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE)
-erroutdisable:
-#endif
+errout_with_waitints:
 
   stm32_configwaitints(priv, 0, 0, 0);
 #ifdef CONFIG_STM32L4_SDMMC_DMA


Mime
View raw message