~aleteoryx/muditaos

da4f9ea2e2df9c7fd5ef7f7a0981a5f26d210c3f — Alek Rudnik 4 years ago 5418f9b
[EGD-7423] FSL MMC driver may stuck in inifinite loop

There was an issue in FSL MMC driver.
Proper fix would be to swith to never 2.10 version - as it looks
like the issues is solved there - but this is out of scope of
this Jira case.
M module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.c => module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.c +25 -2
@@ 1865,7 1865,11 @@ static status_t MMC_Write(
    }

    /* Wait for the card's buffer to be not full to write to improve the write performance. */
    while ((GET_SDMMCHOST_STATUS(card->host.base) & CARD_DATA0_STATUS_MASK) != CARD_DATA0_NOT_BUSY) {}
    error = MMC_PollingCardStatusBusy(card);
    if(kStatus_Success != error)
    {
        return error;
    }

    /* Wait for the card write process complete */
    if (kStatus_Success != MMC_WaitWriteComplete(card)) {


@@ 2264,7 2268,11 @@ status_t MMC_EraseGroups(mmc_card_t *card, uint32_t startGroup, uint32_t endGrou
    }

    /* Wait for the card's buffer to be not full to write to improve the write performance. */
    while ((GET_SDMMCHOST_STATUS(card->host.base) & CARD_DATA0_STATUS_MASK) != CARD_DATA0_NOT_BUSY) {}
    status_t error = MMC_PollingCardStatusBusy(card);
    if(kStatus_Success != error)
    {
        return error;
    }

    if (kStatus_Success != MMC_WaitWriteComplete(card)) {
        return kStatus_SDMMC_WaitWriteCompleteFailed;


@@ 2631,3 2639,18 @@ status_t MMC_StopBoot(mmc_card_t *card, uint32_t bootMode)

    return kStatus_Success;
}

status_t MMC_PollingCardStatusBusy(mmc_card_t *card)
{
    int retries = 0;
    const int maxRetries = 10000;
    do {
        if ((GET_SDMMCHOST_STATUS(card->host.base) & CARD_DATA0_STATUS_MASK) == CARD_DATA0_NOT_BUSY) {
            return kStatus_Success;
        }
        // yeld 
        SDMMCHOST_Delay(0);
    } while (retries++ < maxRetries);
    
    return kStatus_SDMMC_PollingCardIdleFailed;
}

M module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.h => module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.h +12 -0
@@ 356,6 356,18 @@ extern "C"
     */
    status_t MMC_SetMaxEraseUnitSize(mmc_card_t *card);

    /*!
     * @brief Polling card idle status.
     *
     * This function can be used to poll the status from busy to idle.
     *
     * @param card Card descriptor.
     *
     * @retval kStatus_SDMMC_TransferFailed Command tranfer failed.
     * @retval kStatus_Success Operate successfully.
     */
    status_t MMC_PollingCardStatusBusy(mmc_card_t *card);

/* @} */
#if defined(__cplusplus)
}

M module-bsp/board/rt1051/bsp/eMMC/fsl_sdmmc_common.h => module-bsp/board/rt1051/bsp/eMMC/fsl_sdmmc_common.h +1 -0
@@ 124,6 124,7 @@ enum _sdmmc_status
    kStatus_SDMMC_CardDetectFailed         = MAKE_STATUS(kStatusGroup_SDMMC, 39U), /*!<  card detect failed */
    kStatus_SDMMC_PartitioningFailed       = MAKE_STATUS(kStatusGroup_SDMMC, 40U), /*!<  Partitioning failed */
    kStatus_SDMMC_PartitioningNotSupported = MAKE_STATUS(kStatusGroup_SDMMC, 41U), /*!<  Partitioning not supported */
    kStatus_SDMMC_PollingCardIdleFailed    = MAKE_STATUS(kStatusGroup_SDMMC, 42U), /*!< polling card idle status failed */
};

/*! @brief card operation voltage */

M module-platform/rt1051/src/disk_emmc.cpp => module-platform/rt1051/src/disk_emmc.cpp +3 -2
@@ 105,8 105,9 @@ namespace purefs::blkdev
            return statusBlkDevFail;
        }
        // Wait for the card's buffer to become empty
        while ((GET_SDMMCHOST_STATUS(mmcCard->host.base) & CARD_DATA0_STATUS_MASK) != CARD_DATA0_NOT_BUSY) {
            taskYIELD();
        auto error = MMC_PollingCardStatusBusy(mmcCard.get());
        if (kStatus_Success != error) {
            return error;
        }
        if (pmState == pm_state::suspend) {
            driverUSDHC->Enable();

M module-vfs/drivers/src/thirdparty/lwext4/ext4_bdev.cpp => module-vfs/drivers/src/thirdparty/lwext4/ext4_bdev.cpp +1 -1
@@ 69,7 69,7 @@ namespace purefs::fs::drivers::ext4::internal
                }
                const auto err = diskmm->read(ctx->disk_h, buf, blk_id, blk_cnt);
                if (err) {
                    LOG_ERROR("Sector write error errno: %i", err);
                    LOG_ERROR("Sector read error errno: %i", err);
                }
                return -err;
            }