mmc: core: Fix error paths for UHS-II card init and re-init
authorUlf Hansson <ulf.hansson@linaro.org>
Tue, 29 Oct 2024 13:17:49 +0000 (14:17 +0100)
committerUlf Hansson <ulf.hansson@linaro.org>
Wed, 30 Oct 2024 11:02:15 +0000 (12:02 +0100)
The error path didn't manage the removal of the allocated mmc_card
correctly. Let's fix this to avoid potential memory leaks.

While at it, move the assignment of host->card to slightly later in the
init process and drop also a somewhat silly dev_warn() when CMD8 fails.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Message-ID: <20241029131752.226764-4-ulf.hansson@linaro.org>

drivers/mmc/core/sd_uhs2.c

index f0d631b..618b46c 100644 (file)
@@ -827,24 +827,28 @@ static int sd_uhs2_init_card(struct mmc_host *host, struct mmc_card *oldcard)
 
        err = sd_uhs2_config_read(host, card);
        if (err)
-               return err;
+               goto err;
 
        err = sd_uhs2_config_write(host, card);
        if (err)
-               return err;
+               goto err;
 
-       host->card = card;
        /* If change speed to Range B, need to GO_DORMANT_STATE */
        if (host->ios.timing == MMC_TIMING_UHS2_SPEED_B ||
            host->ios.timing == MMC_TIMING_UHS2_SPEED_B_HD) {
                err = sd_uhs2_go_dormant_state(host, node_id);
                if (err)
-                       return err;
+                       goto err;
        }
 
        host->uhs2_sd_tran = true;
-
+       host->card = card;
        return 0;
+
+err:
+       if (!oldcard)
+               mmc_remove_card(card);
+       return err;
 }
 
 /*
@@ -855,7 +859,7 @@ static int sd_uhs2_init_card(struct mmc_host *host, struct mmc_card *oldcard)
  * survives a soft reset through the GO_DORMANT_STATE command.
  */
 static int sd_uhs2_legacy_init(struct mmc_host *host, struct mmc_card *card,
-                              struct mmc_card *oldcard)
+                              bool reinit)
 {
        int err;
        u32 cid[4];
@@ -873,17 +877,15 @@ static int sd_uhs2_legacy_init(struct mmc_host *host, struct mmc_card *card,
 
        /* Send CMD8 to communicate SD interface operation condition */
        err = mmc_send_if_cond(host, host->ocr_avail);
-       if (err) {
-               dev_warn(mmc_dev(host), "CMD8 error\n");
-               goto err;
-       }
+       if (err)
+               return err;
 
        /*
         * Probe SD card working voltage.
         */
        err = mmc_send_app_op_cond(host, 0, &ocr);
        if (err)
-               goto err;
+               return err;
 
        card->ocr = ocr;
 
@@ -907,20 +909,18 @@ static int sd_uhs2_legacy_init(struct mmc_host *host, struct mmc_card *card,
 
        err = mmc_send_app_op_cond(host, ocr, &rocr);
        if (err)
-               goto err;
+               return err;
 
        err = mmc_send_cid(host, cid);
        if (err)
-               goto err;
+               return err;
 
-       if (oldcard) {
-               if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
+       if (reinit) {
+               if (memcmp(cid, card->raw_cid, sizeof(cid)) != 0) {
                        pr_debug("%s: Perhaps the card was replaced\n",
                                 mmc_hostname(host));
                        return -ENOENT;
                }
-
-               card = oldcard;
        } else {
                memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
                mmc_decode_cid(card);
@@ -931,29 +931,29 @@ static int sd_uhs2_legacy_init(struct mmc_host *host, struct mmc_card *card,
         */
        err = mmc_send_relative_addr(host, &card->rca);
        if (err)
-               goto err;
+               return err;
 
        err = mmc_sd_get_csd(card, false);
        if (err)
-               goto err;
+               return err;
 
        /*
         * Select card, as all following commands rely on that.
         */
        err = mmc_select_card(card);
        if (err)
-               goto err;
+               return err;
 
        /*
         * Fetch SCR from card.
         */
        err = mmc_app_send_scr(card);
        if (err)
-               goto err;
+               return err;
 
        err = mmc_decode_scr(card);
        if (err)
-               goto err;
+               return err;
 
        /*
         * Switch to high power consumption mode.
@@ -989,9 +989,6 @@ static int sd_uhs2_legacy_init(struct mmc_host *host, struct mmc_card *card,
 
        kfree(status);
        return 0;
-
-err:
-       return err;
 }
 
 static int sd_uhs2_reinit(struct mmc_host *host)
@@ -1011,7 +1008,7 @@ static int sd_uhs2_reinit(struct mmc_host *host)
        if (err)
                return err;
 
-       return sd_uhs2_legacy_init(host, card, card);
+       return sd_uhs2_legacy_init(host, card, true);
 }
 
 static void sd_uhs2_remove(struct mmc_host *host)
@@ -1172,9 +1169,9 @@ static int sd_uhs2_attach(struct mmc_host *host)
        if (err)
                goto err;
 
-       err = sd_uhs2_legacy_init(host, host->card, NULL);
+       err = sd_uhs2_legacy_init(host, host->card, false);
        if (err)
-               goto err;
+               goto remove_card;
 
        mmc_attach_bus(host, &sd_uhs2_ops);
 
@@ -1185,13 +1182,11 @@ static int sd_uhs2_attach(struct mmc_host *host)
                goto remove_card;
 
        mmc_claim_host(host);
-
        return 0;
 
 remove_card:
        sd_uhs2_remove(host);
        mmc_claim_host(host);
-
 err:
        mmc_detach_bus(host);
        sd_uhs2_power_off(host);