diff --git a/arch/arm/src/cxd56xx/cxd56_sdhci.c b/arch/arm/src/cxd56xx/cxd56_sdhci.c index 1d96f9850b50a..fcb9746bc56a9 100644 --- a/arch/arm/src/cxd56xx/cxd56_sdhci.c +++ b/arch/arm/src/cxd56xx/cxd56_sdhci.c @@ -398,9 +398,8 @@ static int cxd56_sdio_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void cxd56_sdio_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t cxd56_sdio_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t cxd56_sdio_eventwait(FAR struct sdio_dev_s *dev); static void cxd56_sdio_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int cxd56_sdio_registercallback(FAR struct sdio_dev_s *dev, @@ -2494,7 +2493,7 @@ static int cxd56_sdio_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void cxd56_sdio_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev; uint32_t waitints; @@ -2523,6 +2522,32 @@ static void cxd56_sdio_waitenable(FAR struct sdio_dev_s *dev, /* Enable event-related interrupts */ cxd56_configwaitints(priv, waitints, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a corner case */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + cxd56_eventtimeout, (wdparm_t)priv); + if (ret != OK) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2546,8 +2571,7 @@ static void cxd56_sdio_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t cxd56_sdio_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t cxd56_sdio_eventwait(FAR struct sdio_dev_s *dev) { struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2561,30 +2585,6 @@ static sdio_eventset_t cxd56_sdio_eventwait(FAR struct sdio_dev_s *dev, DEBUGASSERT((priv->waitevents != 0 && priv->wkupevent == 0) || (priv->waitevents == 0 && priv->wkupevent != 0)); - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a corner case */ - - if (!timeout) - { - return SDIOWAIT_TIMEOUT; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - cxd56_eventtimeout, (wdparm_t)priv); - if (ret != OK) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - /* Loop until the event (or the timeout occurs). Race conditions are * avoided by calling cxd56_waitenable prior to triggering the logic that * will cause the wait to terminate. Under certain race conditions, the diff --git a/arch/arm/src/imxrt/imxrt_usdhc.c b/arch/arm/src/imxrt/imxrt_usdhc.c index 22cd605f8e076..4665be2be0d88 100644 --- a/arch/arm/src/imxrt/imxrt_usdhc.c +++ b/arch/arm/src/imxrt/imxrt_usdhc.c @@ -350,9 +350,8 @@ static int imxrt_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void imxrt_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t imxrt_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t imxrt_eventwait(FAR struct sdio_dev_s *dev); static void imxrt_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int imxrt_registercallback(FAR struct sdio_dev_s *dev, @@ -2627,7 +2626,7 @@ static int imxrt_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void imxrt_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct imxrt_dev_s *priv = (struct imxrt_dev_s *)dev; uint32_t waitints; @@ -2660,6 +2659,33 @@ static void imxrt_waitenable(FAR struct sdio_dev_s *dev, /* Enable event-related interrupts */ imxrt_configwaitints(priv, waitints, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a corner case */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + imxrt_eventtimeout, (wdparm_t)priv); + + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2683,8 +2709,7 @@ static void imxrt_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t imxrt_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t imxrt_eventwait(FAR struct sdio_dev_s *dev) { struct imxrt_dev_s *priv = (struct imxrt_dev_s *)dev; sdio_eventset_t wkupevent = 0; int ret; @@ -2698,31 +2723,6 @@ static sdio_eventset_t imxrt_eventwait(FAR struct sdio_dev_s *dev, DEBUGASSERT((priv->waitevents != 0 && priv->wkupevent == 0) || (priv->waitevents == 0 && priv->wkupevent != 0)); - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a corner case */ - - if (!timeout) - { - return SDIOWAIT_TIMEOUT; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - imxrt_eventtimeout, (wdparm_t)priv); - - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - /* Loop until the event (or the timeout occurs). Race conditions are * avoided by calling imxrt_waitenable prior to triggering the logic * that will cause the wait to terminate. Under certain race diff --git a/arch/arm/src/kinetis/kinetis_sdhc.c b/arch/arm/src/kinetis/kinetis_sdhc.c index f843a9440fec1..e9114dbbf9b0b 100644 --- a/arch/arm/src/kinetis/kinetis_sdhc.c +++ b/arch/arm/src/kinetis/kinetis_sdhc.c @@ -329,9 +329,8 @@ static int kinetis_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void kinetis_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t - kinetis_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t kinetis_eventwait(FAR struct sdio_dev_s *dev); static void kinetis_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int kinetis_registercallback(FAR struct sdio_dev_s *dev, @@ -2430,7 +2429,7 @@ static int kinetis_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void kinetis_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; uint32_t waitints; @@ -2459,6 +2458,32 @@ static void kinetis_waitenable(FAR struct sdio_dev_s *dev, /* Enable event-related interrupts */ kinetis_configwaitints(priv, waitints, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a corner case */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + kinetis_eventtimeout, (wdparm_t)priv); + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2482,8 +2507,7 @@ static void kinetis_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t kinetis_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t kinetis_eventwait(FAR struct sdio_dev_s *dev) { struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2497,30 +2521,6 @@ static sdio_eventset_t kinetis_eventwait(FAR struct sdio_dev_s *dev, DEBUGASSERT((priv->waitevents != 0 && priv->wkupevent == 0) || (priv->waitevents == 0 && priv->wkupevent != 0)); - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a corner case */ - - if (!timeout) - { - return SDIOWAIT_TIMEOUT; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - kinetis_eventtimeout, (wdparm_t)priv); - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - /* Loop until the event (or the timeout occurs). Race conditions are * avoided by calling kinetis_waitenable prior to triggering the logic * that will cause the wait to terminate. Under certain race conditions, diff --git a/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c b/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c index c0a653d61a693..0b28df15fc361 100644 --- a/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c +++ b/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c @@ -384,9 +384,8 @@ static int lpc17_40_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void lpc17_40_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t - lpc17_40_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t lpc17_40_eventwait(FAR struct sdio_dev_s *dev); static void lpc17_40_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int lpc17_40_registercallback(FAR struct sdio_dev_s *dev, @@ -2237,10 +2236,11 @@ static int lpc17_40_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void lpc17_40_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct lpc17_40_dev_s *priv = (struct lpc17_40_dev_s *)dev; uint32_t waitmask; + int ret; DEBUGASSERT(priv != NULL); @@ -2272,6 +2272,33 @@ static void lpc17_40_waitenable(FAR struct sdio_dev_s *dev, putreg32(SDCARD_WAITALL_ICR, LPC17_40_SDCARD_CLEAR); lpc17_40_configwaitints(priv, waitmask, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + + /* Yes.. Handle a cornercase: The user request a timeout event but + * with timeout == 0? + */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + lpc17_40_eventtimeout, (wdparm_t)priv); + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2295,8 +2322,7 @@ static void lpc17_40_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t lpc17_40_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t lpc17_40_eventwait(FAR struct sdio_dev_s *dev) { struct lpc17_40_dev_s *priv = (struct lpc17_40_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2311,35 +2337,6 @@ static sdio_eventset_t lpc17_40_eventwait(FAR struct sdio_dev_s *dev, flags = enter_critical_section(); DEBUGASSERT(priv->waitevents != 0 || priv->wkupevent != 0); - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a cornercase: The user request a timeout event but - * with timeout == 0? - */ - - if (!timeout) - { - /* Then just tell the caller that we already timed out */ - - wkupevent = SDIOWAIT_TIMEOUT; - goto errout; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - lpc17_40_eventtimeout, (wdparm_t)priv); - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - /* Loop until the event (or the timeout occurs). Race conditions are * avoided by calling lpc17_40_waitenable prior to triggering the logic * that will cause the wait to terminate. Under certain race conditions, @@ -2388,7 +2385,6 @@ static sdio_eventset_t lpc17_40_eventwait(FAR struct sdio_dev_s *dev, priv->xfrflags = 0; #endif -errout: leave_critical_section(flags); lpc17_40_dumpsamples(priv); return wkupevent; diff --git a/arch/arm/src/lpc43xx/lpc43_sdmmc.c b/arch/arm/src/lpc43xx/lpc43_sdmmc.c index 644b9e9eef3b8..af4294675c19e 100644 --- a/arch/arm/src/lpc43xx/lpc43_sdmmc.c +++ b/arch/arm/src/lpc43xx/lpc43_sdmmc.c @@ -325,9 +325,8 @@ static int lpc43_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void lpc43_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t - lpc43_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t lpc43_eventwait(FAR struct sdio_dev_s *dev); static void lpc43_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static void lpc43_callback(struct lpc43_dev_s *priv); @@ -2194,7 +2193,7 @@ static int lpc43_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void lpc43_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct lpc43_dev_s *priv = (struct lpc43_dev_s *)dev; uint32_t waitmask; @@ -2229,6 +2228,34 @@ static void lpc43_waitenable(FAR struct sdio_dev_s *dev, /* Enable event-related interrupts */ lpc43_config_waitints(priv, waitmask, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a cornercase: The user request a timeout event but + * with timeout == 0? + */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + lpc43_eventtimeout, (wdparm_t)priv); + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2252,8 +2279,7 @@ static void lpc43_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t lpc43_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t lpc43_eventwait(FAR struct sdio_dev_s *dev) { struct lpc43_dev_s *priv = (struct lpc43_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2270,35 +2296,6 @@ static sdio_eventset_t lpc43_eventwait(FAR struct sdio_dev_s *dev, flags = enter_critical_section(); DEBUGASSERT(priv->waitevents != 0 || priv->wkupevent != 0); - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a cornercase: The user request a timeout event but - * with timeout == 0? - */ - - if (!timeout) - { - /* Then just tell the caller that we already timed out */ - - wkupevent = SDIOWAIT_TIMEOUT; - goto errout; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - lpc43_eventtimeout, (wdparm_t)priv); - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - /* Loop until the event (or the timeout occurs). Race conditions are * avoided by calling lpc43_waitenable prior to triggering the logic that * will cause the wait to terminate. Under certain race conditions, the diff --git a/arch/arm/src/lpc54xx/lpc54_sdmmc.c b/arch/arm/src/lpc54xx/lpc54_sdmmc.c index b1d05cd723b53..5c4e9086d6b3d 100644 --- a/arch/arm/src/lpc54xx/lpc54_sdmmc.c +++ b/arch/arm/src/lpc54xx/lpc54_sdmmc.c @@ -324,9 +324,8 @@ static int lpc54_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void lpc54_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t - lpc54_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t lpc54_eventwait(FAR struct sdio_dev_s *dev); static void lpc54_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static void lpc54_callback(struct lpc54_dev_s *priv); @@ -2189,7 +2188,7 @@ static int lpc54_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void lpc54_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev; uint32_t waitmask; @@ -2224,6 +2223,34 @@ static void lpc54_waitenable(FAR struct sdio_dev_s *dev, /* Enable event-related interrupts */ lpc54_config_waitints(priv, waitmask, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a cornercase: The user request a timeout event but + * with timeout == 0? + */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + lpc54_eventtimeout, (wdparm_t)priv); + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2247,8 +2274,7 @@ static void lpc54_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t lpc54_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t lpc54_eventwait(FAR struct sdio_dev_s *dev) { struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2265,35 +2291,6 @@ static sdio_eventset_t lpc54_eventwait(FAR struct sdio_dev_s *dev, flags = enter_critical_section(); DEBUGASSERT(priv->waitevents != 0 || priv->wkupevent != 0); - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a cornercase: The user request a timeout event but - * with timeout == 0? - */ - - if (!timeout) - { - /* Then just tell the caller that we already timed out */ - - wkupevent = SDIOWAIT_TIMEOUT; - goto errout; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - lpc54_eventtimeout, (wdparm_t)priv); - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - /* Loop until the event (or the timeout occurs). Race conditions are * avoided by calling lpc54_waitenable prior to triggering the logic that * will cause the wait to terminate. Under certain race conditions, the diff --git a/arch/arm/src/sam34/sam_hsmci.c b/arch/arm/src/sam34/sam_hsmci.c index ca6a7bb431b0f..762bc7b646b70 100644 --- a/arch/arm/src/sam34/sam_hsmci.c +++ b/arch/arm/src/sam34/sam_hsmci.c @@ -489,9 +489,8 @@ static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void sam_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t - sam_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev); static void sam_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int sam_registercallback(FAR struct sdio_dev_s *dev, @@ -2233,7 +2232,7 @@ static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, ****************************************************************************/ static void sam_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; uint32_t waitmask; @@ -2268,6 +2267,32 @@ static void sam_waitenable(FAR struct sdio_dev_s *dev, */ sam_configwaitints(priv, waitmask, eventset); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a cornercase */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + sam_eventtimeout, (wdparm_t)priv); + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2291,8 +2316,7 @@ static void sam_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2310,35 +2334,6 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, sam_enableints(priv); - /* There is a race condition here... the event may have completed before - * we get here. In this case waitevents will be zero, but wkupevents will - * be non-zero (and, hopefully, the semaphore count will also be non-zero). - */ - - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a cornercase */ - - if (!timeout) - { - return SDIOWAIT_TIMEOUT; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - sam_eventtimeout, (wdparm_t)priv); - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - /* Loop until the event (or the timeout occurs). Race conditions are * avoided by calling sam_waitenable prior to triggering the logic that * will cause the wait to terminate. Under certain race conditions, the diff --git a/arch/arm/src/sama5/sam_hsmci.c b/arch/arm/src/sama5/sam_hsmci.c index f5deb35260cbd..5f5685ec96d16 100644 --- a/arch/arm/src/sama5/sam_hsmci.c +++ b/arch/arm/src/sama5/sam_hsmci.c @@ -572,9 +572,8 @@ static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void sam_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t - sam_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev); static void sam_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int sam_registercallback(FAR struct sdio_dev_s *dev, @@ -2651,7 +2650,7 @@ static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, ****************************************************************************/ static void sam_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; uint32_t waitmask; @@ -2686,6 +2685,41 @@ static void sam_waitenable(FAR struct sdio_dev_s *dev, */ sam_configwaitints(priv, waitmask, eventset); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a cornercase */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer. I am not sure why this is, but I am + * currently seeing some additional delays when DMA is used. + */ + + if (priv->txbusy) + { + /* TX transfers can be VERY long in the worst case */ + + timeout = MAX(5000, timeout); + } + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + sam_eventtimeout, (wdparm_t)priv); + if (ret < 0) + { + lcderr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2709,8 +2743,7 @@ static void sam_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2728,44 +2761,6 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, sam_enableints(priv); - /* There is a race condition here... the event may have completed before - * we get here. In this case waitevents will be zero, but wkupevent will - * be non-zero (and, hopefully, the semaphore count will also be non-zero). - */ - - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a cornercase */ - - if (!timeout) - { - return SDIOWAIT_TIMEOUT; - } - - /* Start the watchdog timer. I am not sure why this is, but I am - * currently seeing some additional delays when DMA is used. - */ - - if (priv->txbusy) - { - /* TX transfers can be VERY long in the worst case */ - - timeout = MAX(5000, timeout); - } - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - sam_eventtimeout, (wdparm_t)priv); - if (ret < 0) - { - lcderr("ERROR: wd_start failed: %d\n", ret); - } - } - /* Loop until the event (or the timeout occurs). Race conditions are * avoided by calling sam_waitenable prior to triggering the logic that * will cause the wait to terminate. Under certain race conditions, the diff --git a/arch/arm/src/sama5/sam_sdmmc.c b/arch/arm/src/sama5/sam_sdmmc.c index e502796f11132..0de021e0a542a 100644 --- a/arch/arm/src/sama5/sam_sdmmc.c +++ b/arch/arm/src/sama5/sam_sdmmc.c @@ -344,9 +344,8 @@ static int sam_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void sam_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev); static void sam_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int sam_registercallback(FAR struct sdio_dev_s *dev, @@ -2831,7 +2830,7 @@ static int sam_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void sam_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; uint32_t waitints; @@ -2864,6 +2863,33 @@ static void sam_waitenable(FAR struct sdio_dev_s *dev, /* Enable event-related interrupts */ sam_configwaitints(priv, waitints, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a corner case */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + sam_eventtimeout, (wdparm_t)priv); + + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2887,11 +2913,10 @@ static void sam_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; - sdio_eventset_t wkupevent = 0; int ret; + sdio_eventset_t wkupevent = 0; /* There is a race condition here... the event may have completed before * we get here. In this case waitevents will be zero, but wkupevents @@ -2902,31 +2927,6 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, DEBUGASSERT((priv->waitevents != 0 && priv->wkupevent == 0) || (priv->waitevents == 0 && priv->wkupevent != 0)); - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a corner case */ - - if (!timeout) - { - return SDIOWAIT_TIMEOUT; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - sam_eventtimeout, (wdparm_t)priv); - - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - /* Loop until the event (or the timeout occurs). Race conditions are * avoided by calling sam_waitenable prior to triggering the logic * that will cause the wait to terminate. Under certain race diff --git a/arch/arm/src/samv7/sam_hsmci.c b/arch/arm/src/samv7/sam_hsmci.c index a924af30c736b..53e13de532313 100644 --- a/arch/arm/src/samv7/sam_hsmci.c +++ b/arch/arm/src/samv7/sam_hsmci.c @@ -507,9 +507,8 @@ static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void sam_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t - sam_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev); static void sam_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int sam_registercallback(FAR struct sdio_dev_s *dev, @@ -2696,7 +2695,7 @@ static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, ****************************************************************************/ static void sam_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; uint32_t waitmask; @@ -2731,6 +2730,41 @@ static void sam_waitenable(FAR struct sdio_dev_s *dev, */ sam_configwaitints(priv, waitmask, eventset); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a cornercase */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer. I am not sure why this is, but I am + * currently seeing some additional delays when DMA is used. + */ + + if (priv->txbusy) + { + /* TX transfers can be VERY long in the worst case */ + + timeout = MAX(5000, timeout); + } + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + sam_eventtimeout, (wdparm_t)priv); + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2754,8 +2788,7 @@ static void sam_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2776,44 +2809,6 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, sam_enableints(priv); - /* There is a race condition here... the event may have completed before - * we get here. In this case waitevents will be zero, but wkupevent will - * be non-zero (and, hopefully, the semaphore count will also be non-zero). - */ - - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a cornercase */ - - if (!timeout) - { - return SDIOWAIT_TIMEOUT; - } - - /* Start the watchdog timer. I am not sure why this is, but I am - * currently seeing some additional delays when DMA is used. - */ - - if (priv->txbusy) - { - /* TX transfers can be VERY long in the worst case */ - - timeout = MAX(5000, timeout); - } - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - sam_eventtimeout, (wdparm_t)priv); - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - /* Loop until the event (or the timeout occurs). Race conditions are * avoided by calling sam_waitenable prior to triggering the logic that * will cause the wait to terminate. Under certain race conditions, the diff --git a/arch/arm/src/stm32/stm32_sdio.c b/arch/arm/src/stm32/stm32_sdio.c index 9d52301f893dd..898e32bf12f17 100644 --- a/arch/arm/src/stm32/stm32_sdio.c +++ b/arch/arm/src/stm32/stm32_sdio.c @@ -473,9 +473,8 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void stm32_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t - stm32_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev); static void stm32_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int stm32_registercallback(FAR struct sdio_dev_s *dev, @@ -2429,7 +2428,7 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void stm32_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; uint32_t waitmask; @@ -2474,6 +2473,34 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, } stm32_configwaitints(priv, waitmask, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a cornercase: The user request a timeout event but + * with timeout == 0? + */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + stm32_eventtimeout, (wdparm_t)priv); + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2497,8 +2524,7 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2527,35 +2553,6 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, DEBUGASSERT(priv->waitevents != 0 || priv->wkupevent != 0); #endif - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a cornercase: The user request a timeout event but - * with timeout == 0? - */ - - if (!timeout) - { - /* Then just tell the caller that we already timed out */ - - wkupevent = SDIOWAIT_TIMEOUT; - goto errout; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - stm32_eventtimeout, (wdparm_t)priv); - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - #if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0) { @@ -2620,7 +2617,6 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, priv->xfrflags = 0; #endif -errout: leave_critical_section(flags); stm32_dumpsamples(priv); return wkupevent; diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index 6859f16de5402..e4d28aef7baec 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -547,9 +547,8 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void stm32_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t - stm32_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev); static void stm32_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int stm32_registercallback(FAR struct sdio_dev_s *dev, @@ -2689,7 +2688,7 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void stm32_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; uint32_t waitmask; @@ -2734,6 +2733,34 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, } stm32_configwaitints(priv, waitmask, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a cornercase: The user request a timeout event but + * with timeout == 0? + */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + stm32_eventtimeout, (wdparm_t)priv); + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2757,8 +2784,7 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2787,35 +2813,6 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, DEBUGASSERT(priv->waitevents != 0 || priv->wkupevent != 0); #endif - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a cornercase: The user request a timeout event but - * with timeout == 0? - */ - - if (!timeout) - { - /* Then just tell the caller that we already timed out */ - - wkupevent = SDIOWAIT_TIMEOUT; - goto errout; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - stm32_eventtimeout, (wdparm_t)priv); - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - #if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0) { @@ -2880,7 +2877,6 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, priv->xfrflags = 0; #endif -errout: leave_critical_section(flags); stm32_dumpsamples(priv); return wkupevent; diff --git a/arch/arm/src/stm32h7/stm32_sdmmc.c b/arch/arm/src/stm32h7/stm32_sdmmc.c index df3d60a17a60c..e2637762e2d3b 100644 --- a/arch/arm/src/stm32h7/stm32_sdmmc.c +++ b/arch/arm/src/stm32h7/stm32_sdmmc.c @@ -489,9 +489,8 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void stm32_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t -stm32_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev); static void stm32_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int stm32_registercallback(FAR struct sdio_dev_s *dev, @@ -2744,10 +2743,10 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void stm32_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; - uint32_t waitmask; + uint32_t waitmask = 0; DEBUGASSERT(priv != NULL); @@ -2762,12 +2761,20 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, #if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) if ((eventset & SDIOWAIT_WRCOMPLETE) != 0) { - waitmask = SDIOWAIT_WRCOMPLETE; + /* Read pin to see if ready (true) skip timeout */ + + if (stm32_gpioread(priv->d0_gpio)) + { + eventset &= ~SDIOWAIT_TIMEOUT; + } + else + { + waitmask = SDIOWAIT_WRCOMPLETE; + } } else #endif { - waitmask = 0; if ((eventset & SDIOWAIT_CMDDONE) != 0) { waitmask |= STM32_SDMMC_CMDDONE_MASK; @@ -2789,6 +2796,34 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, } stm32_configwaitints(priv, waitmask, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a cornercase: The user request a timeout event but + * with timeout == 0? + */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + stm32_eventtimeout, (wdparm_t)priv); + if (ret < OK) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2812,8 +2847,7 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2842,35 +2876,6 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, DEBUGASSERT(priv->waitevents != 0 || priv->wkupevent != 0); #endif - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a cornercase: The user request a timeout event but - * with timeout == 0? - */ - - if (!timeout) - { - /* Then just tell the caller that we already timed out */ - - wkupevent = SDIOWAIT_TIMEOUT; - goto errout; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - stm32_eventtimeout, (wdparm_t)priv); - if (ret < OK) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - #if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0) { @@ -2932,7 +2937,6 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, stm32_configwaitints(priv, 0, 0, 0); -errout: leave_critical_section(flags); stm32_dumpsamples(priv); return wkupevent; diff --git a/arch/arm/src/stm32l4/stm32l4_sdmmc.c b/arch/arm/src/stm32l4/stm32l4_sdmmc.c index 2e0860f9842ca..ec09890a4f2e8 100644 --- a/arch/arm/src/stm32l4/stm32l4_sdmmc.c +++ b/arch/arm/src/stm32l4/stm32l4_sdmmc.c @@ -500,9 +500,8 @@ static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, /* EVENT handler */ static void stm32_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset); -static sdio_eventset_t - stm32_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); + sdio_eventset_t eventset, uint32_t timeout); +static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev); static void stm32_callbackenable(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); static int stm32_registercallback(FAR struct sdio_dev_s *dev, @@ -2510,7 +2509,7 @@ static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, ****************************************************************************/ static void stm32_waitenable(FAR struct sdio_dev_s *dev, - sdio_eventset_t eventset) + sdio_eventset_t eventset, uint32_t timeout) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; uint32_t waitmask; @@ -2555,6 +2554,34 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, } stm32_configwaitints(priv, waitmask, eventset, 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + int ret; + + /* Yes.. Handle a cornercase: The user request a timeout event but + * with timeout == 0? + */ + + if (!timeout) + { + priv->wkupevent = SDIOWAIT_TIMEOUT; + return; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(&priv->waitwdog, delay, + stm32_eventtimeout, (wdparm_t)priv); + if (ret < 0) + { + mcerr("ERROR: wd_start failed: %d\n", ret); + } + } } /**************************************************************************** @@ -2578,8 +2605,7 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, - uint32_t timeout) +static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; sdio_eventset_t wkupevent = 0; @@ -2608,35 +2634,6 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, DEBUGASSERT(priv->waitevents != 0 || priv->wkupevent != 0); #endif - /* Check if the timeout event is specified in the event set */ - - if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) - { - int delay; - - /* Yes.. Handle a cornercase: The user request a timeout event but - * with timeout == 0? - */ - - if (!timeout) - { - /* Then just tell the caller that we already timed out */ - - wkupevent = SDIOWAIT_TIMEOUT; - goto errout; - } - - /* Start the watchdog timer */ - - delay = MSEC2TICK(timeout); - ret = wd_start(&priv->waitwdog, delay, - stm32_eventtimeout, (wdparm_t)priv); - if (ret < 0) - { - mcerr("ERROR: wd_start failed: %d\n", ret); - } - } - #if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0) { @@ -2701,7 +2698,6 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, priv->xfrflags = 0; #endif -errout: leave_critical_section(flags); stm32_dumpsamples(priv); return wkupevent; diff --git a/drivers/mmcsd/mmcsd_sdio.c b/drivers/mmcsd/mmcsd_sdio.c index 00186957ca882..226f56f09f394 100644 --- a/drivers/mmcsd/mmcsd_sdio.c +++ b/drivers/mmcsd/mmcsd_sdio.c @@ -178,7 +178,7 @@ static int mmcsd_verifystate(FAR struct mmcsd_state_s *priv, static bool mmcsd_wrprotected(FAR struct mmcsd_state_s *priv); static int mmcsd_eventwait(FAR struct mmcsd_state_s *priv, - sdio_eventset_t failevents, uint32_t timeout); + sdio_eventset_t failevents); static int mmcsd_transferready(FAR struct mmcsd_state_s *priv); #ifndef CONFIG_MMCSD_MULTIBLOCK_DISABLE static int mmcsd_stoptransmission(FAR struct mmcsd_state_s *priv); @@ -486,8 +486,8 @@ static int mmsd_get_scr(FAR struct mmcsd_state_s *priv, uint32_t scr[2]) SDIO_RECVSETUP(priv->dev, (FAR uint8_t *)scr, 8); SDIO_WAITENABLE(priv->dev, - SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | - SDIOWAIT_ERROR); + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, + MMCSD_SCR_DATADELAY); /* Send CMD55 APP_CMD with argument as card's RCA */ @@ -496,6 +496,7 @@ static int mmsd_get_scr(FAR struct mmcsd_state_s *priv, uint32_t scr[2]) if (ret != OK) { ferr("ERROR: RECVR1 for CMD55 failed: %d\n", ret); + SDIO_CANCEL(priv->dev); return ret; } @@ -512,8 +513,7 @@ static int mmsd_get_scr(FAR struct mmcsd_state_s *priv, uint32_t scr[2]) /* Wait for data to be transferred */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, - MMCSD_SCR_DATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); if (ret != OK) { ferr("ERROR: mmcsd_eventwait for READ DATA failed: %d\n", ret); @@ -1153,13 +1153,13 @@ static bool mmcsd_wrprotected(FAR struct mmcsd_state_s *priv) ****************************************************************************/ static int mmcsd_eventwait(FAR struct mmcsd_state_s *priv, - sdio_eventset_t failevents, uint32_t timeout) + sdio_eventset_t failevents) { sdio_eventset_t wkupevent; /* Wait for the set of events enabled by SDIO_EVENTENABLE. */ - wkupevent = SDIO_EVENTWAIT(priv->dev, timeout); + wkupevent = SDIO_EVENTWAIT(priv->dev); /* SDIO_EVENTWAIT returns the event set containing the event(s) that ended * the wait. It should always be non-zero, but may contain failure as @@ -1228,8 +1228,7 @@ static int mmcsd_transferready(FAR struct mmcsd_state_s *priv) */ #if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, - MMCSD_BLOCK_WDATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); if (ret != OK) { ferr("ERROR: mmcsd_eventwait for transfer ready failed: %d\n", ret); @@ -1440,7 +1439,8 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv, SDIO_BLOCKSETUP(priv->dev, priv->blocksize, 1); SDIO_WAITENABLE(priv->dev, - SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, + MMCSD_BLOCK_RDATADELAY); #ifdef CONFIG_SDIO_DMA if ((priv->caps & SDIO_CAPS_DMASUPPORTED) != 0) @@ -1449,6 +1449,7 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv, if (ret != OK) { finfo("SDIO_DMARECVSETUP: error %d\n", ret); + SDIO_CANCEL(priv->dev); return ret; } } @@ -1475,8 +1476,7 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv, /* Then wait for the data transfer to complete */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, - MMCSD_BLOCK_RDATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); if (ret != OK) { ferr("ERROR: CMD17 transfer failed: %d\n", ret); @@ -1576,7 +1576,8 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv, SDIO_BLOCKSETUP(priv->dev, priv->blocksize, nblocks); SDIO_WAITENABLE(priv->dev, - SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, + nblocks * MMCSD_BLOCK_RDATADELAY); #ifdef CONFIG_SDIO_DMA if ((priv->caps & SDIO_CAPS_DMASUPPORTED) != 0) @@ -1585,6 +1586,7 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv, if (ret != OK) { finfo("SDIO_DMARECVSETUP: error %d\n", ret); + SDIO_CANCEL(priv->dev); return ret; } } @@ -1609,8 +1611,7 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv, /* Wait for the transfer to complete */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, - nblocks * MMCSD_BLOCK_RDATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); if (ret != OK) { ferr("ERROR: CMD18 transfer failed: %d\n", ret); @@ -1798,7 +1799,8 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv, SDIO_BLOCKSETUP(priv->dev, priv->blocksize, 1); SDIO_WAITENABLE(priv->dev, - SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, + MMCSD_BLOCK_WDATADELAY); #ifdef CONFIG_SDIO_DMA if ((priv->caps & SDIO_CAPS_DMASUPPORTED) != 0) @@ -1807,6 +1809,7 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv, if (ret != OK) { finfo("SDIO_DMASENDSETUP: error %d\n", ret); + SDIO_CANCEL(priv->dev); return ret; } } @@ -1834,9 +1837,7 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv, /* Wait for the transfer to complete */ - ret = mmcsd_eventwait(priv, - SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, - MMCSD_BLOCK_WDATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); if (ret != OK) { ferr("ERROR: CMD24 transfer failed: %d\n", ret); @@ -1852,7 +1853,8 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv, #if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) /* Arm the write complete detection with timeout */ - SDIO_WAITENABLE(priv->dev, SDIOWAIT_WRCOMPLETE | SDIOWAIT_TIMEOUT); + SDIO_WAITENABLE(priv->dev, SDIOWAIT_WRCOMPLETE | SDIOWAIT_TIMEOUT, + MMCSD_BLOCK_WDATADELAY); #endif /* On success, return the number of blocks written */ @@ -2003,7 +2005,8 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv, SDIO_BLOCKSETUP(priv->dev, priv->blocksize, nblocks); SDIO_WAITENABLE(priv->dev, - SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, + nblocks * MMCSD_BLOCK_WDATADELAY); #ifdef CONFIG_SDIO_DMA if ((priv->caps & SDIO_CAPS_DMASUPPORTED) != 0) @@ -2012,6 +2015,7 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv, if (ret != OK) { finfo("SDIO_DMASENDSETUP: error %d\n", ret); + SDIO_CANCEL(priv->dev); return ret; } } @@ -2041,8 +2045,7 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv, /* Wait for the transfer to complete */ - evret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, - nblocks * MMCSD_BLOCK_WDATADELAY); + evret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); if (evret != OK) { ferr("ERROR: CMD25 transfer failed: %d\n", evret); @@ -2077,7 +2080,8 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv, #if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) /* Arm the write complete detection with timeout */ - SDIO_WAITENABLE(priv->dev, SDIOWAIT_WRCOMPLETE | SDIOWAIT_TIMEOUT); + SDIO_WAITENABLE(priv->dev, SDIOWAIT_WRCOMPLETE | SDIOWAIT_TIMEOUT, + nblocks * MMCSD_BLOCK_WDATADELAY); #endif /* On success, return the number of blocks written */ @@ -2845,7 +2849,8 @@ static int mmcsd_read_csd(FAR struct mmcsd_state_s *priv) SDIO_BLOCKSETUP(priv->dev, 512, 1); SDIO_WAITENABLE(priv->dev, - SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, + MMCSD_BLOCK_RDATADELAY); #ifdef CONFIG_SDIO_DMA if ((priv->caps & SDIO_CAPS_DMASUPPORTED) != 0) @@ -2854,6 +2859,7 @@ static int mmcsd_read_csd(FAR struct mmcsd_state_s *priv) if (ret != OK) { finfo("SDIO_DMARECVSETUP: error %d\n", ret); + SDIO_CANCEL(priv->dev); return ret; } } @@ -2873,13 +2879,13 @@ static int mmcsd_read_csd(FAR struct mmcsd_state_s *priv) if (ret != OK) { ferr("ERROR: Could not get MMC extended CSD register: %d\n", ret); + SDIO_CANCEL(priv->dev); return ret; } /* Then wait for the data transfer to complete */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, - MMCSD_BLOCK_RDATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); if (ret != OK) { ferr("ERROR: CMD17 transfer failed: %d\n", ret); diff --git a/drivers/wireless/ieee80211/bcm43xxx/mmc_sdio.c b/drivers/wireless/ieee80211/bcm43xxx/mmc_sdio.c index 915baae315ce6..4d8355c8acd98 100644 --- a/drivers/wireless/ieee80211/bcm43xxx/mmc_sdio.c +++ b/drivers/wireless/ieee80211/bcm43xxx/mmc_sdio.c @@ -229,7 +229,8 @@ int sdio_io_rw_extended(FAR struct sdio_dev_s *dev, bool write, SDIO_BLOCKSETUP(dev, blocklen, nblocks); SDIO_WAITENABLE(dev, - SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, + SDIO_CMD53_TIMEOUT_MS); if (write) { @@ -242,7 +243,7 @@ int sdio_io_rw_extended(FAR struct sdio_dev_s *dev, bool write, SDIO_DMASENDSETUP(dev, buf, blocklen * nblocks); SDIO_SENDCMD(dev, SD_ACMD53, arg.value); - wkupevent = SDIO_EVENTWAIT(dev, SDIO_CMD53_TIMEOUT_MS); + wkupevent = SDIO_EVENTWAIT(dev); ret = SDIO_RECVR5(dev, SD_ACMD53, &data); } else @@ -251,7 +252,7 @@ int sdio_io_rw_extended(FAR struct sdio_dev_s *dev, bool write, ret = SDIO_RECVR5(dev, SD_ACMD53, &data); SDIO_DMASENDSETUP(dev, buf, blocklen * nblocks); - wkupevent = SDIO_EVENTWAIT(dev, SDIO_CMD53_TIMEOUT_MS); + wkupevent = SDIO_EVENTWAIT(dev); } } else @@ -260,7 +261,7 @@ int sdio_io_rw_extended(FAR struct sdio_dev_s *dev, bool write, SDIO_DMARECVSETUP(dev, buf, blocklen * nblocks); SDIO_SENDCMD(dev, SD_ACMD53, arg.value); - wkupevent = SDIO_EVENTWAIT(dev, SDIO_CMD53_TIMEOUT_MS); + wkupevent = SDIO_EVENTWAIT(dev); ret = SDIO_RECVR5(dev, SD_ACMD53, &data); } diff --git a/include/nuttx/sdio.h b/include/nuttx/sdio.h index befd694147bb7..71edb7dbe2015 100644 --- a/include/nuttx/sdio.h +++ b/include/nuttx/sdio.h @@ -683,7 +683,7 @@ * ****************************************************************************/ -#define SDIO_WAITENABLE(dev,eventset) ((dev)->waitenable(dev,eventset)) +#define SDIO_WAITENABLE(dev,eventset,timeout) ((dev)->waitenable(dev,eventset,timeout)) /**************************************************************************** * Name: SDIO_EVENTWAIT @@ -706,7 +706,7 @@ * ****************************************************************************/ -#define SDIO_EVENTWAIT(dev,timeout) ((dev)->eventwait(dev,timeout)) +#define SDIO_EVENTWAIT(dev) ((dev)->eventwait(dev)) /**************************************************************************** * Name: SDIO_CALLBACKENABLE @@ -920,8 +920,9 @@ struct sdio_dev_s /* Event/Callback support */ - void (*waitenable)(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); - sdio_eventset_t (*eventwait)(FAR struct sdio_dev_s *dev, uint32_t timeout); + void (*waitenable)(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset, + uint32_t timeout); + sdio_eventset_t (*eventwait)(FAR struct sdio_dev_s *dev); void (*callbackenable)(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset);