Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48b5352e authored by Pierre Ossman's avatar Pierre Ossman
Browse files

mmc_test: test oversized sg lists



Add tests that make sure the driver properly checks the blocks and
blksz fields and doesn't assume the sg list has a size that perfectly
matches the current request.

Signed-off-by: default avatarPierre Ossman <drzeus@drzeus.cx>
parent 2661081f
Loading
Loading
Loading
Loading
+82 −3
Original line number Diff line number Diff line
@@ -388,14 +388,16 @@ static int mmc_test_transfer(struct mmc_test_card *test,
	int ret, i;
	unsigned long flags;

	BUG_ON(blocks * blksz > BUFFER_SIZE);

	if (write) {
		for (i = 0;i < blocks * blksz;i++)
			test->scratch[i] = i;
	} else {
		memset(test->scratch, 0, BUFFER_SIZE);
		memset(test->scratch, 0, blocks * blksz);
	}
	local_irq_save(flags);
	sg_copy_from_buffer(sg, sg_len, test->scratch, BUFFER_SIZE);
	sg_copy_from_buffer(sg, sg_len, test->scratch, blocks * blksz);
	local_irq_restore(flags);

	ret = mmc_test_set_blksize(test, blksz);
@@ -442,7 +444,7 @@ static int mmc_test_transfer(struct mmc_test_card *test,
		}
	} else {
		local_irq_save(flags);
		sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE);
		sg_copy_to_buffer(sg, sg_len, test->scratch, blocks * blksz);
		local_irq_restore(flags);
		for (i = 0;i < blocks * blksz;i++) {
			if (test->scratch[i] != (u8)i)
@@ -803,6 +805,69 @@ static int mmc_test_multi_xfersize_read(struct mmc_test_card *test)
	return 0;
}

static int mmc_test_bigsg_write(struct mmc_test_card *test)
{
	int ret;
	unsigned int size;
	struct scatterlist sg;

	if (test->card->host->max_blk_count == 1)
		return RESULT_UNSUP_HOST;

	size = PAGE_SIZE * 2;
	size = min(size, test->card->host->max_req_size);
	size = min(size, test->card->host->max_seg_size);
	size = min(size, test->card->host->max_blk_count * 512);

	memset(test->buffer, 0, BUFFER_SIZE);

	if (size < 1024)
		return RESULT_UNSUP_HOST;

	sg_init_table(&sg, 1);
	sg_init_one(&sg, test->buffer, BUFFER_SIZE);

	ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
	if (ret)
		return ret;

	return 0;
}

static int mmc_test_bigsg_read(struct mmc_test_card *test)
{
	int ret, i;
	unsigned int size;
	struct scatterlist sg;

	if (test->card->host->max_blk_count == 1)
		return RESULT_UNSUP_HOST;

	size = PAGE_SIZE * 2;
	size = min(size, test->card->host->max_req_size);
	size = min(size, test->card->host->max_seg_size);
	size = min(size, test->card->host->max_blk_count * 512);

	if (size < 1024)
		return RESULT_UNSUP_HOST;

	memset(test->buffer, 0xCD, BUFFER_SIZE);

	sg_init_table(&sg, 1);
	sg_init_one(&sg, test->buffer, BUFFER_SIZE);
	ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
	if (ret)
		return ret;

	/* mmc_test_transfer() doesn't check for read overflows */
	for (i = size;i < BUFFER_SIZE;i++) {
		if (test->buffer[i] != 0xCD)
			return RESULT_FAIL;
	}

	return 0;
}

#ifdef CONFIG_HIGHMEM

static int mmc_test_write_high(struct mmc_test_card *test)
@@ -1006,6 +1071,20 @@ static const struct mmc_test_case mmc_test_cases[] = {
		.run = mmc_test_multi_xfersize_read,
	},

	{
		.name = "Over-sized SG list write",
		.prepare = mmc_test_prepare_write,
		.run = mmc_test_bigsg_write,
		.cleanup = mmc_test_cleanup,
	},

	{
		.name = "Over-sized SG list read",
		.prepare = mmc_test_prepare_read,
		.run = mmc_test_bigsg_read,
		.cleanup = mmc_test_cleanup,
	},

#ifdef CONFIG_HIGHMEM

	{