mmc: card: Add eMMC4.5 write packed commands unit-tests

Expose the following packed commands tests:
- Test the write packed commands list preparation
- Simulate a returned error code
- Send an invalid packed command to the card

Change-Id: I23a15f94571da3ff9553a342dc37e1a8de6827c6
Signed-off-by: Lee Susman <lsusman@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
Signed-off-by: Tatyana Brokhman <tlinder@codeaurora.org>
This commit is contained in:
Tatyana Brokhman 2012-10-09 13:50:56 +02:00 committed by Subhash Jadavani
parent 8a0840d289
commit fececf257d
5 changed files with 1607 additions and 11 deletions

View file

@ -68,13 +68,3 @@ config MMC_TEST
This driver is only of interest to those developing or
testing a host driver. Most people should say N here.
config MMC_BLOCK_TEST
tristate "MMC block test"
depends on MMC_BLOCK && IOSCHED_TEST
help
MMC block test can be used with test iosched to test the MMC block
device.
Currently used to test eMMC 4.5 features (packed commands, sanitize,
BKOPs).

View file

@ -8,3 +8,4 @@ obj-$(CONFIG_MMC_TEST) += mmc_test.o
obj-$(CONFIG_SDIO_UART) += sdio_uart.o
obj-$(CONFIG_MMC_BLOCK_TEST) += mmc_block_test.o

View file

@ -1742,6 +1742,64 @@ void mmc_blk_init_packed_statistics(struct mmc_card *card)
}
EXPORT_SYMBOL(mmc_blk_init_packed_statistics);
void print_mmc_packing_stats(struct mmc_card *card)
{
int i;
int max_num_of_packed_reqs = 0;
if ((!card) || (!card->wr_pack_stats.packing_events))
return;
max_num_of_packed_reqs = card->ext_csd.max_packed_writes;
spin_lock(&card->wr_pack_stats.lock);
pr_info("%s: write packing statistics:\n",
mmc_hostname(card->host));
for (i = 1 ; i <= max_num_of_packed_reqs ; ++i) {
if (card->wr_pack_stats.packing_events[i] != 0)
pr_info("%s: Packed %d reqs - %d times\n",
mmc_hostname(card->host), i,
card->wr_pack_stats.packing_events[i]);
}
pr_info("%s: stopped packing due to the following reasons:\n",
mmc_hostname(card->host));
if (card->wr_pack_stats.pack_stop_reason[EXCEEDS_SEGMENTS])
pr_info("%s: %d times: exceedmax num of segments\n",
mmc_hostname(card->host),
card->wr_pack_stats.pack_stop_reason[EXCEEDS_SEGMENTS]);
if (card->wr_pack_stats.pack_stop_reason[EXCEEDS_SECTORS])
pr_info("%s: %d times: exceeding the max num of sectors\n",
mmc_hostname(card->host),
card->wr_pack_stats.pack_stop_reason[EXCEEDS_SECTORS]);
if (card->wr_pack_stats.pack_stop_reason[WRONG_DATA_DIR])
pr_info("%s: %d times: wrong data direction\n",
mmc_hostname(card->host),
card->wr_pack_stats.pack_stop_reason[WRONG_DATA_DIR]);
if (card->wr_pack_stats.pack_stop_reason[FLUSH_OR_DISCARD])
pr_info("%s: %d times: flush or discard\n",
mmc_hostname(card->host),
card->wr_pack_stats.pack_stop_reason[FLUSH_OR_DISCARD]);
if (card->wr_pack_stats.pack_stop_reason[EMPTY_QUEUE])
pr_info("%s: %d times: empty queue\n",
mmc_hostname(card->host),
card->wr_pack_stats.pack_stop_reason[EMPTY_QUEUE]);
if (card->wr_pack_stats.pack_stop_reason[REL_WRITE])
pr_info("%s: %d times: rel write\n",
mmc_hostname(card->host),
card->wr_pack_stats.pack_stop_reason[REL_WRITE]);
if (card->wr_pack_stats.pack_stop_reason[THRESHOLD])
pr_info("%s: %d times: Threshold\n",
mmc_hostname(card->host),
card->wr_pack_stats.pack_stop_reason[THRESHOLD]);
spin_unlock(&card->wr_pack_stats.lock);
}
EXPORT_SYMBOL(print_mmc_packing_stats);
static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req)
{
struct request_queue *q = mq->queue;
@ -1960,7 +2018,18 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq,
brq->data.sg_len = mmc_queue_map_sg(mq, mqrq);
mqrq->mmc_active.mrq = &brq->mrq;
mqrq->mmc_active.err_check = mmc_blk_packed_err_check;
/*
* This is intended for packed commands tests usage - in case these
* functions are not in use the respective pointers are NULL
*/
if (mq->err_check_fn)
mqrq->mmc_active.err_check = mq->err_check_fn;
else
mqrq->mmc_active.err_check = mmc_blk_packed_err_check;
if (mq->packed_test_fn)
mq->packed_test_fn(mq->queue, mqrq);
mmc_queue_bounce_pre(mqrq);
}

File diff suppressed because it is too large Load diff

View file

@ -61,6 +61,8 @@ struct mmc_queue {
bool wr_packing_enabled;
int num_of_potential_packed_wr_reqs;
int num_wr_reqs_to_start_packing;
int (*err_check_fn) (struct mmc_card *, struct mmc_async_req *);
void (*packed_test_fn) (struct request_queue *, struct mmc_queue_req *);
};
extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
@ -79,4 +81,6 @@ extern void mmc_packed_clean(struct mmc_queue *);
extern int mmc_access_rpmb(struct mmc_queue *);
extern void print_mmc_packing_stats(struct mmc_card *card);
#endif