diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-09-08 01:01:14 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-09-08 01:01:14 -0300 |
commit | e5fd91f1ef340da553f7a79da9540c3db711c937 (patch) | |
tree | b11842027dc6641da63f4bcc524f8678263304a3 /drivers/mmc/card | |
parent | 2a9b0348e685a63d97486f6749622b61e9e3292f (diff) |
Linux-libre 4.2-gnu
Diffstat (limited to 'drivers/mmc/card')
-rw-r--r-- | drivers/mmc/card/block.c | 17 | ||||
-rw-r--r-- | drivers/mmc/card/mmc_test.c | 104 | ||||
-rw-r--r-- | drivers/mmc/card/queue.c | 6 | ||||
-rw-r--r-- | drivers/mmc/card/queue.h | 1 |
4 files changed, 34 insertions, 94 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 31d2627d9..a1b820fcb 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -915,6 +915,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, if (!err) break; + /* Re-tune if needed */ + mmc_retune_recheck(card->host); + prev_cmd_status_valid = false; pr_err("%s: error %d sending status command, %sing\n", req->rq_disk->disk_name, err, retry ? "retry" : "abort"); @@ -1206,6 +1209,7 @@ static int mmc_blk_err_check(struct mmc_card *card, mmc_active); struct mmc_blk_request *brq = &mq_mrq->brq; struct request *req = mq_mrq->req; + int need_retune = card->host->need_retune; int ecc_err = 0, gen_err = 0; /* @@ -1273,6 +1277,12 @@ static int mmc_blk_err_check(struct mmc_card *card, } if (brq->data.error) { + if (need_retune && !brq->retune_retry_done) { + pr_info("%s: retrying because a re-tune was needed\n", + req->rq_disk->disk_name); + brq->retune_retry_done = 1; + return MMC_BLK_RETRY; + } pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n", req->rq_disk->disk_name, brq->data.error, (unsigned)blk_rq_pos(req), @@ -1832,7 +1842,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; struct mmc_blk_request *brq = &mq->mqrq_cur->brq; - int ret = 1, disable_multi = 0, retry = 0, type; + int ret = 1, disable_multi = 0, retry = 0, type, retune_retry_done = 0; enum mmc_blk_status status; struct mmc_queue_req *mq_rq; struct request *req = rqc; @@ -1918,6 +1928,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) goto start_new_req; break; case MMC_BLK_RETRY: + retune_retry_done = brq->retune_retry_done; if (retry++ < 5) break; /* Fall through */ @@ -1980,6 +1991,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) mmc_start_req(card->host, &mq_rq->mmc_active, NULL); } + mq_rq->brq.retune_retry_done = retune_retry_done; } } while (ret); @@ -2221,7 +2233,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) * The CSD capacity field is in units of read_blkbits. * set_capacity takes units of 512 bytes. */ - size = card->csd.capacity << (card->csd.read_blkbits - 9); + size = (typeof(sector_t))card->csd.capacity + << (card->csd.read_blkbits - 9); } return mmc_blk_alloc_req(card, &card->dev, size, false, NULL, diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index 53b741398..b78cf5d40 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -268,8 +268,6 @@ static int mmc_test_wait_busy(struct mmc_test_card *test) static int mmc_test_buffer_transfer(struct mmc_test_card *test, u8 *buffer, unsigned addr, unsigned blksz, int write) { - int ret; - struct mmc_request mrq = {0}; struct mmc_command cmd = {0}; struct mmc_command stop = {0}; @@ -292,11 +290,7 @@ static int mmc_test_buffer_transfer(struct mmc_test_card *test, if (data.error) return data.error; - ret = mmc_test_wait_busy(test); - if (ret) - return ret; - - return 0; + return mmc_test_wait_busy(test); } static void mmc_test_free_mem(struct mmc_test_mem *mem) @@ -826,9 +820,7 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test, mmc_test_nonblock_reset(&mrq1, &cmd1, &stop1, &data1); } - done_areq = cur_areq; - cur_areq = other_areq; - other_areq = done_areq; + swap(cur_areq, other_areq); dev_addr += blocks; } @@ -994,11 +986,7 @@ static int mmc_test_basic_write(struct mmc_test_card *test) sg_init_one(&sg, test->buffer, 512); - ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1); - if (ret) - return ret; - - return 0; + return mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1); } static int mmc_test_basic_read(struct mmc_test_card *test) @@ -1012,44 +1000,29 @@ static int mmc_test_basic_read(struct mmc_test_card *test) sg_init_one(&sg, test->buffer, 512); - ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 0); - if (ret) - return ret; - - return 0; + return mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 0); } static int mmc_test_verify_write(struct mmc_test_card *test) { - int ret; struct scatterlist sg; sg_init_one(&sg, test->buffer, 512); - ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1); - if (ret) - return ret; - - return 0; + return mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1); } static int mmc_test_verify_read(struct mmc_test_card *test) { - int ret; struct scatterlist sg; sg_init_one(&sg, test->buffer, 512); - ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0); - if (ret) - return ret; - - return 0; + return mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0); } static int mmc_test_multi_write(struct mmc_test_card *test) { - int ret; unsigned int size; struct scatterlist sg; @@ -1066,16 +1039,11 @@ static int mmc_test_multi_write(struct mmc_test_card *test) sg_init_one(&sg, test->buffer, size); - ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); - if (ret) - return ret; - - return 0; + return mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); } static int mmc_test_multi_read(struct mmc_test_card *test) { - int ret; unsigned int size; struct scatterlist sg; @@ -1092,11 +1060,7 @@ static int mmc_test_multi_read(struct mmc_test_card *test) sg_init_one(&sg, test->buffer, size); - ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); - if (ret) - return ret; - - return 0; + return mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); } static int mmc_test_pow2_write(struct mmc_test_card *test) @@ -1263,11 +1227,7 @@ static int mmc_test_xfersize_write(struct mmc_test_card *test) if (ret) return ret; - ret = mmc_test_broken_transfer(test, 1, 512, 1); - if (ret) - return ret; - - return 0; + return mmc_test_broken_transfer(test, 1, 512, 1); } static int mmc_test_xfersize_read(struct mmc_test_card *test) @@ -1278,11 +1238,7 @@ static int mmc_test_xfersize_read(struct mmc_test_card *test) if (ret) return ret; - ret = mmc_test_broken_transfer(test, 1, 512, 0); - if (ret) - return ret; - - return 0; + return mmc_test_broken_transfer(test, 1, 512, 0); } static int mmc_test_multi_xfersize_write(struct mmc_test_card *test) @@ -1296,11 +1252,7 @@ static int mmc_test_multi_xfersize_write(struct mmc_test_card *test) if (ret) return ret; - ret = mmc_test_broken_transfer(test, 2, 512, 1); - if (ret) - return ret; - - return 0; + return mmc_test_broken_transfer(test, 2, 512, 1); } static int mmc_test_multi_xfersize_read(struct mmc_test_card *test) @@ -1314,48 +1266,33 @@ static int mmc_test_multi_xfersize_read(struct mmc_test_card *test) if (ret) return ret; - ret = mmc_test_broken_transfer(test, 2, 512, 0); - if (ret) - return ret; - - return 0; + return mmc_test_broken_transfer(test, 2, 512, 0); } #ifdef CONFIG_HIGHMEM static int mmc_test_write_high(struct mmc_test_card *test) { - int ret; struct scatterlist sg; sg_init_table(&sg, 1); sg_set_page(&sg, test->highmem, 512, 0); - ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1); - if (ret) - return ret; - - return 0; + return mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1); } static int mmc_test_read_high(struct mmc_test_card *test) { - int ret; struct scatterlist sg; sg_init_table(&sg, 1); sg_set_page(&sg, test->highmem, 512, 0); - ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0); - if (ret) - return ret; - - return 0; + return mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0); } static int mmc_test_multi_write_high(struct mmc_test_card *test) { - int ret; unsigned int size; struct scatterlist sg; @@ -1373,16 +1310,11 @@ static int mmc_test_multi_write_high(struct mmc_test_card *test) sg_init_table(&sg, 1); sg_set_page(&sg, test->highmem, size, 0); - ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); - if (ret) - return ret; - - return 0; + return mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); } static int mmc_test_multi_read_high(struct mmc_test_card *test) { - int ret; unsigned int size; struct scatterlist sg; @@ -1400,11 +1332,7 @@ static int mmc_test_multi_read_high(struct mmc_test_card *test) sg_init_table(&sg, 1); sg_set_page(&sg, test->highmem, size, 0); - ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); - if (ret) - return ret; - - return 0; + return mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); } #else diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 8efa3684a..b5a2b145d 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -56,7 +56,6 @@ static int mmc_queue_thread(void *d) down(&mq->thread_sem); do { struct request *req = NULL; - struct mmc_queue_req *tmp; unsigned int cmd_flags = 0; spin_lock_irq(q->queue_lock); @@ -69,6 +68,7 @@ static int mmc_queue_thread(void *d) set_current_state(TASK_RUNNING); cmd_flags = req ? req->cmd_flags : 0; mq->issue_fn(mq, req); + cond_resched(); if (mq->flags & MMC_QUEUE_NEW_REQUEST) { mq->flags &= ~MMC_QUEUE_NEW_REQUEST; continue; /* fetch again */ @@ -86,9 +86,7 @@ static int mmc_queue_thread(void *d) mq->mqrq_prev->brq.mrq.data = NULL; mq->mqrq_prev->req = NULL; - tmp = mq->mqrq_prev; - mq->mqrq_prev = mq->mqrq_cur; - mq->mqrq_cur = tmp; + swap(mq->mqrq_prev, mq->mqrq_cur); } else { if (kthread_should_stop()) { set_current_state(TASK_RUNNING); diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index 99e6521e6..36cddab57 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h @@ -12,6 +12,7 @@ struct mmc_blk_request { struct mmc_command cmd; struct mmc_command stop; struct mmc_data data; + int retune_retry_done; }; enum mmc_packed_type { |