aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2008-07-20 18:14:52 -0400
committerPierre Ossman <drzeus@drzeus.cx>2008-07-23 08:42:08 -0400
commit48b5352ea1891455eb8e824cf7d92f66931a090f (patch)
tree5068eb9fb3d16e0f1353a662b48c370fdabfcd7e /drivers
parent2661081f5ab9cb25359d27f88707a018cf4e68e9 (diff)
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: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/card/mmc_test.c85
1 files changed, 82 insertions, 3 deletions
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index 6fc13d4c634a..25296011df59 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -388,14 +388,16 @@ static int mmc_test_transfer(struct mmc_test_card *test,
388 int ret, i; 388 int ret, i;
389 unsigned long flags; 389 unsigned long flags;
390 390
391 BUG_ON(blocks * blksz > BUFFER_SIZE);
392
391 if (write) { 393 if (write) {
392 for (i = 0;i < blocks * blksz;i++) 394 for (i = 0;i < blocks * blksz;i++)
393 test->scratch[i] = i; 395 test->scratch[i] = i;
394 } else { 396 } else {
395 memset(test->scratch, 0, BUFFER_SIZE); 397 memset(test->scratch, 0, blocks * blksz);
396 } 398 }
397 local_irq_save(flags); 399 local_irq_save(flags);
398 sg_copy_from_buffer(sg, sg_len, test->scratch, BUFFER_SIZE); 400 sg_copy_from_buffer(sg, sg_len, test->scratch, blocks * blksz);
399 local_irq_restore(flags); 401 local_irq_restore(flags);
400 402
401 ret = mmc_test_set_blksize(test, blksz); 403 ret = mmc_test_set_blksize(test, blksz);
@@ -442,7 +444,7 @@ static int mmc_test_transfer(struct mmc_test_card *test,
442 } 444 }
443 } else { 445 } else {
444 local_irq_save(flags); 446 local_irq_save(flags);
445 sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE); 447 sg_copy_to_buffer(sg, sg_len, test->scratch, blocks * blksz);
446 local_irq_restore(flags); 448 local_irq_restore(flags);
447 for (i = 0;i < blocks * blksz;i++) { 449 for (i = 0;i < blocks * blksz;i++) {
448 if (test->scratch[i] != (u8)i) 450 if (test->scratch[i] != (u8)i)
@@ -803,6 +805,69 @@ static int mmc_test_multi_xfersize_read(struct mmc_test_card *test)
803 return 0; 805 return 0;
804} 806}
805 807
808static int mmc_test_bigsg_write(struct mmc_test_card *test)
809{
810 int ret;
811 unsigned int size;
812 struct scatterlist sg;
813
814 if (test->card->host->max_blk_count == 1)
815 return RESULT_UNSUP_HOST;
816
817 size = PAGE_SIZE * 2;
818 size = min(size, test->card->host->max_req_size);
819 size = min(size, test->card->host->max_seg_size);
820 size = min(size, test->card->host->max_blk_count * 512);
821
822 memset(test->buffer, 0, BUFFER_SIZE);
823
824 if (size < 1024)
825 return RESULT_UNSUP_HOST;
826
827 sg_init_table(&sg, 1);
828 sg_init_one(&sg, test->buffer, BUFFER_SIZE);
829
830 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
831 if (ret)
832 return ret;
833
834 return 0;
835}
836
837static int mmc_test_bigsg_read(struct mmc_test_card *test)
838{
839 int ret, i;
840 unsigned int size;
841 struct scatterlist sg;
842
843 if (test->card->host->max_blk_count == 1)
844 return RESULT_UNSUP_HOST;
845
846 size = PAGE_SIZE * 2;
847 size = min(size, test->card->host->max_req_size);
848 size = min(size, test->card->host->max_seg_size);
849 size = min(size, test->card->host->max_blk_count * 512);
850
851 if (size < 1024)
852 return RESULT_UNSUP_HOST;
853
854 memset(test->buffer, 0xCD, BUFFER_SIZE);
855
856 sg_init_table(&sg, 1);
857 sg_init_one(&sg, test->buffer, BUFFER_SIZE);
858 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
859 if (ret)
860 return ret;
861
862 /* mmc_test_transfer() doesn't check for read overflows */
863 for (i = size;i < BUFFER_SIZE;i++) {
864 if (test->buffer[i] != 0xCD)
865 return RESULT_FAIL;
866 }
867
868 return 0;
869}
870
806#ifdef CONFIG_HIGHMEM 871#ifdef CONFIG_HIGHMEM
807 872
808static int mmc_test_write_high(struct mmc_test_card *test) 873static int mmc_test_write_high(struct mmc_test_card *test)
@@ -1006,6 +1071,20 @@ static const struct mmc_test_case mmc_test_cases[] = {
1006 .run = mmc_test_multi_xfersize_read, 1071 .run = mmc_test_multi_xfersize_read,
1007 }, 1072 },
1008 1073
1074 {
1075 .name = "Over-sized SG list write",
1076 .prepare = mmc_test_prepare_write,
1077 .run = mmc_test_bigsg_write,
1078 .cleanup = mmc_test_cleanup,
1079 },
1080
1081 {
1082 .name = "Over-sized SG list read",
1083 .prepare = mmc_test_prepare_read,
1084 .run = mmc_test_bigsg_read,
1085 .cleanup = mmc_test_cleanup,
1086 },
1087
1009#ifdef CONFIG_HIGHMEM 1088#ifdef CONFIG_HIGHMEM
1010 1089
1011 { 1090 {