From 77614a99499b7316340fff738ba07b35736bcfe5 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 29 Nov 2018 15:43:37 +0100 Subject: [PATCH 1/3] drivers: mmc: check mmc_reset_to_idle return Signed-off-by: Yann Gautier --- drivers/mmc/mmc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 02bf770e5..4160003c8 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -386,7 +386,10 @@ static int mmc_send_op_cond(void) int ret, n; unsigned int resp_data[4]; - mmc_reset_to_idle(); + ret = mmc_reset_to_idle(); + if (ret != 0) { + return ret; + }; for (n = 0; n < SEND_OP_COND_MAX_RETRIES; n++) { ret = mmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE | @@ -416,7 +419,10 @@ static int mmc_enumerate(unsigned int clk, unsigned int bus_width) ops->init(); - mmc_reset_to_idle(); + ret = mmc_reset_to_idle(); + if (ret != 0) { + return ret; + }; if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) { ret = mmc_send_op_cond(); From ba7f9bfd8e6201eb98c82de3d1bf62323819312f Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 29 Nov 2018 15:44:04 +0100 Subject: [PATCH 2/3] stm32mp: check stm32_sdmmc2_mmc_init return Signed-off-by: Yann Gautier --- plat/st/stm32mp1/bl2_io_storage.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plat/st/stm32mp1/bl2_io_storage.c b/plat/st/stm32mp1/bl2_io_storage.c index fdbd4bfd0..b1125d15d 100644 --- a/plat/st/stm32mp1/bl2_io_storage.c +++ b/plat/st/stm32mp1/bl2_io_storage.c @@ -282,7 +282,11 @@ void stm32mp1_io_setup(void) } params.device_info = &device_info; - stm32_sdmmc2_mmc_init(¶ms); + if (stm32_sdmmc2_mmc_init(¶ms) != 0) { + ERROR("SDMMC%u init failed\n", + boot_context->boot_interface_instance); + panic(); + } /* Open MMC as a block device to read GPT table */ io_result = register_io_dev_block(&mmc_dev_con); From 1d7bcaa636200cad91e6dcece4333533d697915d Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 30 Nov 2018 15:22:11 +0100 Subject: [PATCH 3/3] drivers: st: mmc: improve error cases in send_cmd function Signed-off-by: Yann Gautier --- drivers/st/mmc/stm32_sdmmc2.c | 52 ++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c index 633a4250e..db5158156 100644 --- a/drivers/st/mmc/stm32_sdmmc2.c +++ b/drivers/st/mmc/stm32_sdmmc2.c @@ -97,7 +97,7 @@ #define SDMMC_STAR_CMDSENT BIT(7) #define SDMMC_STAR_DATAEND BIT(8) #define SDMMC_STAR_DBCKEND BIT(10) -#define SDMMC_STAR_DPSMACT BIT(11) +#define SDMMC_STAR_DPSMACT BIT(12) #define SDMMC_STAR_RXFIFOHF BIT(15) #define SDMMC_STAR_RXFIFOE BIT(19) #define SDMMC_STAR_IDMATE BIT(27) @@ -266,21 +266,22 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) mmio_write_32(base + SDMMC_CMDR, cmd_reg); + status = mmio_read_32(base + SDMMC_STAR); + start = get_timer(0); - do { - status = mmio_read_32(base + SDMMC_STAR); - + while ((status & flags_cmd) == 0U) { if (get_timer(start) > TIMEOUT_10_MS) { err = -ETIMEDOUT; ERROR("%s: timeout 10ms (cmd = %d,status = %x)\n", __func__, cmd->cmd_idx, status); - break; + goto err_exit; } - } while ((status & flags_cmd) == 0U); - if (((status & (SDMMC_STAR_CTIMEOUT | SDMMC_STAR_CCRCFAIL)) != 0U) && - (err == 0)) { + status = mmio_read_32(base + SDMMC_STAR); + } + + if ((status & (SDMMC_STAR_CTIMEOUT | SDMMC_STAR_CCRCFAIL)) != 0U) { if ((status & SDMMC_STAR_CTIMEOUT) != 0U) { err = -ETIMEDOUT; /* @@ -300,9 +301,11 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) ERROR("%s: CRCFAIL (cmd = %d,status = %x)\n", __func__, cmd->cmd_idx, status); } + + goto err_exit; } - if (((cmd_reg & SDMMC_CMDR_WAITRESP) != 0U) && (err == 0)) { + if ((cmd_reg & SDMMC_CMDR_WAITRESP) != 0U) { if ((cmd->cmd_idx == MMC_CMD(9)) && ((cmd_reg & SDMMC_CMDR_WAITRESP) == SDMMC_CMDR_WAITRESP)) { /* Need to invert response to match CSD structure */ @@ -324,32 +327,26 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) } } - if ((flags_data == 0U) || (err != 0)) { - if (flags_data != 0U) { - mmio_clrbits_32(base + SDMMC_CMDR, SDMMC_CMDR_CMDTRANS); - } - + if (flags_data == 0U) { mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS); - if ((err != 0) && (flags_data != 0U)) { - return stm32_sdmmc2_stop_transfer(); - } - - return err; + return 0; } + status = mmio_read_32(base + SDMMC_STAR); + start = get_timer(0); - do { - status = mmio_read_32(base + SDMMC_STAR); - + while ((status & flags_data) == 0U) { if (get_timer(start) > TIMEOUT_10_MS) { ERROR("%s: timeout 10ms (cmd = %d,status = %x)\n", __func__, cmd->cmd_idx, status); err = -ETIMEDOUT; - break; + goto err_exit; } - } while ((status & flags_data) == 0U); + + status = mmio_read_32(base + SDMMC_STAR); + }; if ((status & (SDMMC_STAR_DTIMEOUT | SDMMC_STAR_DCRCFAIL | SDMMC_STAR_TXUNDERR | SDMMC_STAR_RXOVERR | @@ -359,11 +356,16 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) err = -EIO; } +err_exit: mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS); mmio_clrbits_32(base + SDMMC_CMDR, SDMMC_CMDR_CMDTRANS); if (err != 0) { - return stm32_sdmmc2_stop_transfer(); + int ret_stop = stm32_sdmmc2_stop_transfer(); + + if (ret_stop != 0) { + return ret_stop; + } } return err;