diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2006-10-04 05:15:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 10:55:15 -0400 |
commit | 176f00ffed3ef94a198326fbf6a5db64f1cf73ad (patch) | |
tree | b436c7dad050c7c86333953c3371a55ac472e795 /drivers | |
parent | 7104e2d5a85b4b786d6a63568beffe1e185547bb (diff) |
[PATCH] mmc: properly use the new multi block-write error handling
Use the new multi block-write error reporting flag and properly tell the block
layer how much data was transferred before the error.
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/mmc_block.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index db0e8ad439a5..c1293f1bda87 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
@@ -158,13 +158,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
158 | { | 158 | { |
159 | struct mmc_blk_data *md = mq->data; | 159 | struct mmc_blk_data *md = mq->data; |
160 | struct mmc_card *card = md->queue.card; | 160 | struct mmc_card *card = md->queue.card; |
161 | struct mmc_blk_request brq; | ||
161 | int ret; | 162 | int ret; |
162 | 163 | ||
163 | if (mmc_card_claim_host(card)) | 164 | if (mmc_card_claim_host(card)) |
164 | goto cmd_err; | 165 | goto cmd_err; |
165 | 166 | ||
166 | do { | 167 | do { |
167 | struct mmc_blk_request brq; | ||
168 | struct mmc_command cmd; | 168 | struct mmc_command cmd; |
169 | u32 readcmd, writecmd; | 169 | u32 readcmd, writecmd; |
170 | 170 | ||
@@ -278,17 +278,27 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
278 | cmd_err: | 278 | cmd_err: |
279 | mmc_card_release_host(card); | 279 | mmc_card_release_host(card); |
280 | 280 | ||
281 | ret = 1; | ||
282 | |||
281 | /* | 283 | /* |
282 | * This is a little draconian, but until we get proper | 284 | * For writes and where the host claims to support proper |
283 | * error handling sorted out here, its the best we can | 285 | * error reporting, we first ok the successful blocks. |
284 | * do - especially as some hosts have no idea how much | 286 | * |
285 | * data was transferred before the error occurred. | 287 | * For reads we just fail the entire chunk as that should |
288 | * be safe in all cases. | ||
286 | */ | 289 | */ |
290 | if (rq_data_dir(req) != READ && | ||
291 | (card->host->caps & MMC_CAP_MULTIWRITE)) { | ||
292 | spin_lock_irq(&md->lock); | ||
293 | ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered); | ||
294 | spin_unlock_irq(&md->lock); | ||
295 | } | ||
296 | |||
287 | spin_lock_irq(&md->lock); | 297 | spin_lock_irq(&md->lock); |
288 | do { | 298 | while (ret) { |
289 | ret = end_that_request_chunk(req, 0, | 299 | ret = end_that_request_chunk(req, 0, |
290 | req->current_nr_sectors << 9); | 300 | req->current_nr_sectors << 9); |
291 | } while (ret); | 301 | } |
292 | 302 | ||
293 | add_disk_randomness(req->rq_disk); | 303 | add_disk_randomness(req->rq_disk); |
294 | blkdev_dequeue_request(req); | 304 | blkdev_dequeue_request(req); |