mmc: don't call switch on old cards
authorPierre Ossman <drzeus@drzeus.cx>
Thu, 31 May 2007 20:25:11 +0000 (22:25 +0200)
committerPierre Ossman <drzeus@drzeus.cx>
Thu, 7 Jun 2007 07:25:58 +0000 (09:25 +0200)
Make sure we don't call the switch function on cards too old to
support it. They should just ignore it, but some have been reported
to lock up instead.

Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
drivers/mmc/core/sd.c

index 5afac2081185325991474f96b67ceb798b129c87..41bfb5dfe6ff1351d1c5845d753c6da3f4bd84e5 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
 
 #include "core.h"
 #include "sysfs.h"
@@ -192,6 +193,16 @@ static int mmc_read_switch(struct mmc_card *card)
        int err;
        u8 *status;
 
+       if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+               return MMC_ERR_NONE;
+
+       if (!(card->csd.cmdclass & CCC_SWITCH)) {
+               printk(KERN_WARNING "%s: card lacks mandatory switch "
+                       "function, performance might suffer.\n",
+                       mmc_hostname(card->host));
+               return MMC_ERR_NONE;
+       }
+
        err = MMC_ERR_FAILED;
 
        status = kmalloc(64, GFP_KERNEL);
@@ -204,10 +215,9 @@ static int mmc_read_switch(struct mmc_card *card)
 
        err = mmc_sd_switch(card, 0, 0, 1, status);
        if (err != MMC_ERR_NONE) {
-               /*
-                * Card not supporting high-speed will ignore the
-                * command.
-                */
+               printk(KERN_WARNING "%s: problem reading switch "
+                       "capabilities, performance might suffer.\n",
+                       mmc_hostname(card->host));
                err = MMC_ERR_NONE;
                goto out;
        }
@@ -229,6 +239,12 @@ static int mmc_switch_hs(struct mmc_card *card)
        int err;
        u8 *status;
 
+       if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+               return MMC_ERR_NONE;
+
+       if (!(card->csd.cmdclass & CCC_SWITCH))
+               return MMC_ERR_NONE;
+
        if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
                return MMC_ERR_NONE;