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/.
This commit is contained in:
Gregory Nutt 2020-04-04 10:38:16 -06:00 committed by Abdelatif Guettouche
parent a6e69a82ad
commit 1501d284c3
14 changed files with 268 additions and 115 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)
{
/* 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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
@ -321,26 +320,6 @@ static int twi_takesem(sem_t *sem)
return nxsem_wait(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
*
@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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