aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/card/block.c21
-rw-r--r--include/linux/mmc/host.h1
2 files changed, 15 insertions, 7 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index c0cb225bbb4734..a1cb21f95302c4 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1030,13 +1030,20 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
if (brq->data.blocks > card->host->max_blk_count)
brq->data.blocks = card->host->max_blk_count;
- /*
- * After a read error, we redo the request one sector at a time
- * in order to accurately determine which sectors can be read
- * successfully.
- */
- if (disable_multi && brq->data.blocks > 1)
- brq->data.blocks = 1;
+ if (brq->data.blocks > 1) {
+ /*
+ * After a read error, we redo the request one sector
+ * at a time in order to accurately determine which
+ * sectors can be read successfully.
+ */
+ if (disable_multi)
+ brq->data.blocks = 1;
+
+ /* Some controllers can't do multiblock reads due to hw bugs */
+ if (card->host->caps2 & MMC_CAP2_NO_MULTI_READ &&
+ rq_data_dir(req) == READ)
+ brq->data.blocks = 1;
+ }
if (brq->data.blocks > 1 || do_rel_wr) {
/* SPI multiblock writes terminate using a special
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 16e9338944e823..a3ac9c48e5de60 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -241,6 +241,7 @@ struct mmc_host {
#define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */
#define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */
#define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff supported */
+#define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */
mmc_pm_flag_t pm_caps; /* supported pm features */
unsigned int power_notify_type;