mirror of https://github.com/hak5/openwrt.git
75 lines
2.7 KiB
Diff
75 lines
2.7 KiB
Diff
|
This patch makes SDHC cards work with the mmc_spi driver.
|
||
|
|
||
|
The problem is that they fail when reading the last block of the card using
|
||
|
a multi-block read. This is because on SDHC the multiple block read has to be
|
||
|
stopped with an explicit STOP command, which needs to be sent to the card
|
||
|
while the incoming transfer is in progress.
|
||
|
The 2.6.3[45] mmc-spi driver sends it after the last block transfer, so the
|
||
|
SDHC card continues reading past the end of the card.
|
||
|
This patch works around this by using single-block reads if we're reading the
|
||
|
last blocks of the card.
|
||
|
-martinwguy, 14 May 2010
|
||
|
|
||
|
Date: Thu, 29 Apr 2010 21:30:36 +0300
|
||
|
From: Mika Westerberg <mika.westerberg@iki.fi>
|
||
|
To: Martin Guy <martinwguy@gmail.com>
|
||
|
|
||
|
On Wed, Apr 21, 2010 at 02:10:08AM +0100, Martin Guy wrote:
|
||
|
>
|
||
|
> the SDHC cards I have don't work at all, spewing tons of:
|
||
|
> mmcblk0: error -38 sending status comand
|
||
|
> mmcblk0: error -38 sending read/write command, response 0x4, card status 0xff04
|
||
|
> end_request: I/O error, dev mmcblk0, sector 7744509
|
||
|
|
||
|
I bought today a new 4GB SDHC card and with that I get similar
|
||
|
errors that you are getting. I hacked around quick fix which seems
|
||
|
to work in my case. I'm wondering whether you could check if it
|
||
|
helps with your SDHC card as well?
|
||
|
|
||
|
This problem is easy to reproduce, just read last sector of the
|
||
|
card (I wrote simple C program but running fdisk -l does the same).
|
||
|
|
||
|
Patch is below.
|
||
|
|
||
|
Thanks,
|
||
|
MW
|
||
|
|
||
|
From: Mika Westerberg <mika.westerberg@iki.fi>
|
||
|
Date: Thu, 29 Apr 2010 21:14:32 +0300
|
||
|
Subject: [PATCH] mmc_block: use single block reads for last block on SPI
|
||
|
|
||
|
Some SD-cards fail when doing multiblock read for last block with SPI host. Real
|
||
|
reason is not known but as workaround we can perform this last read using
|
||
|
multiple single block reads.
|
||
|
|
||
|
Signed-off-by: Mika Westerberg <mika.westerberg@iki.fi>
|
||
|
---
|
||
|
drivers/mmc/card/block.c | 19 +++++++++++++++++++
|
||
|
1 files changed, 19 insertions(+), 0 deletions(-)
|
||
|
|
||
|
--- a/drivers/mmc/card/block.c
|
||
|
+++ b/drivers/mmc/card/block.c
|
||
|
@@ -351,6 +351,22 @@ static int mmc_blk_issue_rw_rq(struct mm
|
||
|
if (brq.data.blocks > card->host->max_blk_count)
|
||
|
brq.data.blocks = card->host->max_blk_count;
|
||
|
|
||
|
+ if (mmc_host_is_spi(card->host)) {
|
||
|
+ /*
|
||
|
+ * Some SD-cards fail when we are reading last block
|
||
|
+ * with multiblock read. In these cases we automatically
|
||
|
+ * use single block reads. This only happens on SPI
|
||
|
+ * hosts.
|
||
|
+ */
|
||
|
+ if (rq_data_dir(req) == READ && brq.data.blocks > 1) {
|
||
|
+ sector_t s = blk_rq_pos(req) + brq.data.blocks;
|
||
|
+
|
||
|
+ if (s >= get_capacity(md->disk)) {
|
||
|
+ disable_multi = 1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
/*
|
||
|
* After a read error, we redo the request one sector at a time
|
||
|
* in order to accurately determine which sectors can be read
|