mmc: sdhci: fix NULL dereference in sdhci_request() tuning
authorChris Ball <cjb@laptop.org>
Mon, 5 Nov 2012 19:29:49 +0000 (14:29 -0500)
committerChris Ball <cjb@laptop.org>
Wed, 7 Nov 2012 20:02:05 +0000 (15:02 -0500)
Commit 473b095a72a9 ("mmc: sdhci: fix incorrect command used in tuning")
introduced a NULL dereference at resume-time if an SD 3.0 host controller
raises the SDHCI_NEEDS_TUNING flag while no card is inserted.  Seen on an
OLPC XO-4 with sdhci-pxav3, but presumably affects other controllers too.

Signed-off-by: Chris Ball <cjb@laptop.org>
Cc: stable <stable@vger.kernel.org> [3.3+]
drivers/mmc/host/sdhci.c

index 949e18c7c05dd6b69bf498ca589e6839734a718a..c7851c0aabce52226d118d50bbe95fe61b4094c2 100644 (file)
@@ -1315,16 +1315,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
                 */
                if ((host->flags & SDHCI_NEEDS_RETUNING) &&
                    !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
-                       /* eMMC uses cmd21 while sd and sdio use cmd19 */
-                       tuning_opcode = mmc->card->type == MMC_TYPE_MMC ?
-                               MMC_SEND_TUNING_BLOCK_HS200 :
-                               MMC_SEND_TUNING_BLOCK;
-                       spin_unlock_irqrestore(&host->lock, flags);
-                       sdhci_execute_tuning(mmc, tuning_opcode);
-                       spin_lock_irqsave(&host->lock, flags);
-
-                       /* Restore original mmc_request structure */
-                       host->mrq = mrq;
+                       if (mmc->card) {
+                               /* eMMC uses cmd21 but sd and sdio use cmd19 */
+                               tuning_opcode =
+                                       mmc->card->type == MMC_TYPE_MMC ?
+                                       MMC_SEND_TUNING_BLOCK_HS200 :
+                                       MMC_SEND_TUNING_BLOCK;
+                               spin_unlock_irqrestore(&host->lock, flags);
+                               sdhci_execute_tuning(mmc, tuning_opcode);
+                               spin_lock_irqsave(&host->lock, flags);
+
+                               /* Restore original mmc_request structure */
+                               host->mrq = mrq;
+                       }
                }
 
                if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))