]> git.baikalelectronics.ru Git - kernel.git/commitdiff
mmc: block: Remove error check of hw_reset on reset
authorChristian Löhle <CLoehle@hyperstone.com>
Thu, 13 Oct 2022 11:16:37 +0000 (11:16 +0000)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 17 Oct 2022 09:51:33 +0000 (11:51 +0200)
Before switching back to the right partition in mmc_blk_reset there used
to be a check if hw_reset was even supported. This return value
was removed, so there is no reason to check. Furthermore ensure
part_curr is not falsely set to a valid value on reset or
partition switch error.

As part of this change the code paths of mmc_blk_reset calls were checked
to ensure no commands are issued after a failed mmc_blk_reset directly
without going through the block layer.

Fixes: 5e46c7dc076a ("mmc: core: Drop superfluous validations in mmc_hw|sw_reset()")
Cc: stable@vger.kernel.org
Signed-off-by: Christian Loehle <cloehle@hyperstone.com>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/e91be6199d04414a91e20611c81bfe1d@hyperstone.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/core/block.c

index 54cd009aee50e9870db70eac04f8490e650bc6e0..db6d8a0999100bdf0a18e4a32abb5a92ffd45b87 100644 (file)
@@ -134,6 +134,7 @@ struct mmc_blk_data {
         * track of the current selected device partition.
         */
        unsigned int    part_curr;
+#define MMC_BLK_PART_INVALID   UINT_MAX        /* Unknown partition active */
        int     area_type;
 
        /* debugfs files (only in main mmc_blk_data) */
@@ -987,33 +988,39 @@ static unsigned int mmc_blk_data_timeout_ms(struct mmc_host *host,
        return ms;
 }
 
+/*
+ * Attempts to reset the card and get back to the requested partition.
+ * Therefore any error here must result in cancelling the block layer
+ * request, it must not be reattempted without going through the mmc_blk
+ * partition sanity checks.
+ */
 static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
                         int type)
 {
        int err;
+       struct mmc_blk_data *main_md = dev_get_drvdata(&host->card->dev);
 
        if (md->reset_done & type)
                return -EEXIST;
 
        md->reset_done |= type;
        err = mmc_hw_reset(host->card);
+       /*
+        * A successful reset will leave the card in the main partition, but
+        * upon failure it might not be, so set it to MMC_BLK_PART_INVALID
+        * in that case.
+        */
+       main_md->part_curr = err ? MMC_BLK_PART_INVALID : main_md->part_type;
+       if (err)
+               return err;
        /* Ensure we switch back to the correct partition */
-       if (err) {
-               struct mmc_blk_data *main_md =
-                       dev_get_drvdata(&host->card->dev);
-               int part_err;
-
-               main_md->part_curr = main_md->part_type;
-               part_err = mmc_blk_part_switch(host->card, md->part_type);
-               if (part_err) {
-                       /*
-                        * We have failed to get back into the correct
-                        * partition, so we need to abort the whole request.
-                        */
-                       return -ENODEV;
-               }
-       }
-       return err;
+       if (mmc_blk_part_switch(host->card, md->part_type))
+               /*
+                * We have failed to get back into the correct
+                * partition, so we need to abort the whole request.
+                */
+               return -ENODEV;
+       return 0;
 }
 
 static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type)
@@ -1871,8 +1878,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
                return;
 
        /* Reset before last retry */
-       if (mqrq->retries + 1 == MMC_MAX_RETRIES)
-               mmc_blk_reset(md, card->host, type);
+       if (mqrq->retries + 1 == MMC_MAX_RETRIES &&
+           mmc_blk_reset(md, card->host, type))
+               return;
 
        /* Command errors fail fast, so use all MMC_MAX_RETRIES */
        if (brq->sbc.error || brq->cmd.error)