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:
parent
8a0840d289
commit
fececf257d
5 changed files with 1607 additions and 11 deletions
|
@ -68,13 +68,3 @@ config MMC_TEST
|
||||||
|
|
||||||
This driver is only of interest to those developing or
|
This driver is only of interest to those developing or
|
||||||
testing a host driver. Most people should say N here.
|
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).
|
|
||||||
|
|
||||||
|
|
|
@ -8,3 +8,4 @@ obj-$(CONFIG_MMC_TEST) += mmc_test.o
|
||||||
|
|
||||||
obj-$(CONFIG_SDIO_UART) += sdio_uart.o
|
obj-$(CONFIG_SDIO_UART) += sdio_uart.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_MMC_BLOCK_TEST) += mmc_block_test.o
|
||||||
|
|
|
@ -1742,6 +1742,64 @@ void mmc_blk_init_packed_statistics(struct mmc_card *card)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mmc_blk_init_packed_statistics);
|
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)
|
static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req)
|
||||||
{
|
{
|
||||||
struct request_queue *q = mq->queue;
|
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);
|
brq->data.sg_len = mmc_queue_map_sg(mq, mqrq);
|
||||||
|
|
||||||
mqrq->mmc_active.mrq = &brq->mrq;
|
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);
|
mmc_queue_bounce_pre(mqrq);
|
||||||
}
|
}
|
||||||
|
|
1532
drivers/mmc/card/mmc_block_test.c
Normal file
1532
drivers/mmc/card/mmc_block_test.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -61,6 +61,8 @@ struct mmc_queue {
|
||||||
bool wr_packing_enabled;
|
bool wr_packing_enabled;
|
||||||
int num_of_potential_packed_wr_reqs;
|
int num_of_potential_packed_wr_reqs;
|
||||||
int num_wr_reqs_to_start_packing;
|
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 *,
|
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 int mmc_access_rpmb(struct mmc_queue *);
|
||||||
|
|
||||||
|
extern void print_mmc_packing_stats(struct mmc_card *card);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue