aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/card
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-19 01:32:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-19 01:32:40 -0400
commita8c91da549f625d0600d5bd7e1831066b55edf0d (patch)
tree494738b095d7c96286c7b0d0d586c7b8fa594f5a /drivers/mmc/card
parent26b95cac5fddb2916e2cef76495073f9c37a7b54 (diff)
parentc07946a3350244d7c3d9bc1032325e04dd11575b (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (53 commits) mmc: dw_mmc: support mmc power control with regulator mmc: dw_mmc: fix suspend/resume operation mmc: dw_mmc: add quirks for unreliable card detect, and capabilities mmc: tmio: fix address in kunmap_atomic() calls mmc: core: reset card voltage after power off mmc: core: export function mmc_do_release_host() mmc: sdio: remember new card RCA when redetecting card mmc: dw_mmc: Remove set-but-unused variable. mmc: sdhci-esdhc-imx: add card detect on custom GPIO for mx25/35 mmc: sdhci-esdhc: broken card detection is not a default quirk mmc: sdhci-esdhc-imx: add write protect on custom GPIO on mx25/35 mmc: msm_sdcc: remove needless cache flush after dma_unmap_sg() mmc: sh_mmcif: support aggressive clock gating mmc: check if mmc cards < 2GB do sector addressing mmc: core: comment on why sdio_reset is done at init time mmc: dw_mmc: support DDR mode mmc: via-sdmmc: Remove set-but-unused variable. mmc: cb710: Return err value in cb710_wait_while_busy() mmc: sdhci-pci: Remove set-but-unused variable. mmc: mxs-mmc: add mmc host driver for i.MX23/28 ...
Diffstat (limited to 'drivers/mmc/card')
-rw-r--r--drivers/mmc/card/Kconfig3
-rw-r--r--drivers/mmc/card/block.c1
-rw-r--r--drivers/mmc/card/mmc_test.c271
3 files changed, 247 insertions, 28 deletions
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig
index 2a876c4099cd..3b1f783bf924 100644
--- a/drivers/mmc/card/Kconfig
+++ b/drivers/mmc/card/Kconfig
@@ -58,12 +58,11 @@ config SDIO_UART
58 58
59config MMC_TEST 59config MMC_TEST
60 tristate "MMC host test driver" 60 tristate "MMC host test driver"
61 default n
62 help 61 help
63 Development driver that performs a series of reads and writes 62 Development driver that performs a series of reads and writes
64 to a memory card in order to expose certain well known bugs 63 to a memory card in order to expose certain well known bugs
65 in host controllers. The tests are executed by writing to the 64 in host controllers. The tests are executed by writing to the
66 "test" file in sysfs under each card. Note that whatever is 65 "test" file in debugfs under each card. Note that whatever is
67 on your card will be overwritten by these tests. 66 on your card will be overwritten by these tests.
68 67
69 This driver is only of interest to those developing or 68 This driver is only of interest to those developing or
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index bfc8a8ae55df..61d233a7c118 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -621,6 +621,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
621 md->disk->private_data = md; 621 md->disk->private_data = md;
622 md->disk->queue = md->queue.queue; 622 md->disk->queue = md->queue.queue;
623 md->disk->driverfs_dev = &card->dev; 623 md->disk->driverfs_dev = &card->dev;
624 set_disk_ro(md->disk, md->read_only);
624 625
625 /* 626 /*
626 * As discussed on lkml, GENHD_FL_REMOVABLE should: 627 * As discussed on lkml, GENHD_FL_REMOVABLE should:
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index 21adc27f4132..5ec8eddfcf6e 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -88,6 +88,7 @@ struct mmc_test_area {
88 * @sectors: amount of sectors to check in one group 88 * @sectors: amount of sectors to check in one group
89 * @ts: time values of transfer 89 * @ts: time values of transfer
90 * @rate: calculated transfer rate 90 * @rate: calculated transfer rate
91 * @iops: I/O operations per second (times 100)
91 */ 92 */
92struct mmc_test_transfer_result { 93struct mmc_test_transfer_result {
93 struct list_head link; 94 struct list_head link;
@@ -95,6 +96,7 @@ struct mmc_test_transfer_result {
95 unsigned int sectors; 96 unsigned int sectors;
96 struct timespec ts; 97 struct timespec ts;
97 unsigned int rate; 98 unsigned int rate;
99 unsigned int iops;
98}; 100};
99 101
100/** 102/**
@@ -226,9 +228,10 @@ static int mmc_test_wait_busy(struct mmc_test_card *test)
226 228
227 if (!busy && mmc_test_busy(&cmd)) { 229 if (!busy && mmc_test_busy(&cmd)) {
228 busy = 1; 230 busy = 1;
229 printk(KERN_INFO "%s: Warning: Host did not " 231 if (test->card->host->caps & MMC_CAP_WAIT_WHILE_BUSY)
230 "wait for busy state to end.\n", 232 printk(KERN_INFO "%s: Warning: Host did not "
231 mmc_hostname(test->card->host)); 233 "wait for busy state to end.\n",
234 mmc_hostname(test->card->host));
232 } 235 }
233 } while (mmc_test_busy(&cmd)); 236 } while (mmc_test_busy(&cmd));
234 237
@@ -494,7 +497,7 @@ static unsigned int mmc_test_rate(uint64_t bytes, struct timespec *ts)
494 */ 497 */
495static void mmc_test_save_transfer_result(struct mmc_test_card *test, 498static void mmc_test_save_transfer_result(struct mmc_test_card *test,
496 unsigned int count, unsigned int sectors, struct timespec ts, 499 unsigned int count, unsigned int sectors, struct timespec ts,
497 unsigned int rate) 500 unsigned int rate, unsigned int iops)
498{ 501{
499 struct mmc_test_transfer_result *tr; 502 struct mmc_test_transfer_result *tr;
500 503
@@ -509,6 +512,7 @@ static void mmc_test_save_transfer_result(struct mmc_test_card *test,
509 tr->sectors = sectors; 512 tr->sectors = sectors;
510 tr->ts = ts; 513 tr->ts = ts;
511 tr->rate = rate; 514 tr->rate = rate;
515 tr->iops = iops;
512 516
513 list_add_tail(&tr->link, &test->gr->tr_lst); 517 list_add_tail(&tr->link, &test->gr->tr_lst);
514} 518}
@@ -519,20 +523,22 @@ static void mmc_test_save_transfer_result(struct mmc_test_card *test,
519static void mmc_test_print_rate(struct mmc_test_card *test, uint64_t bytes, 523static void mmc_test_print_rate(struct mmc_test_card *test, uint64_t bytes,
520 struct timespec *ts1, struct timespec *ts2) 524 struct timespec *ts1, struct timespec *ts2)
521{ 525{
522 unsigned int rate, sectors = bytes >> 9; 526 unsigned int rate, iops, sectors = bytes >> 9;
523 struct timespec ts; 527 struct timespec ts;
524 528
525 ts = timespec_sub(*ts2, *ts1); 529 ts = timespec_sub(*ts2, *ts1);
526 530
527 rate = mmc_test_rate(bytes, &ts); 531 rate = mmc_test_rate(bytes, &ts);
532 iops = mmc_test_rate(100, &ts); /* I/O ops per sec x 100 */
528 533
529 printk(KERN_INFO "%s: Transfer of %u sectors (%u%s KiB) took %lu.%09lu " 534 printk(KERN_INFO "%s: Transfer of %u sectors (%u%s KiB) took %lu.%09lu "
530 "seconds (%u kB/s, %u KiB/s)\n", 535 "seconds (%u kB/s, %u KiB/s, %u.%02u IOPS)\n",
531 mmc_hostname(test->card->host), sectors, sectors >> 1, 536 mmc_hostname(test->card->host), sectors, sectors >> 1,
532 (sectors & 1 ? ".5" : ""), (unsigned long)ts.tv_sec, 537 (sectors & 1 ? ".5" : ""), (unsigned long)ts.tv_sec,
533 (unsigned long)ts.tv_nsec, rate / 1000, rate / 1024); 538 (unsigned long)ts.tv_nsec, rate / 1000, rate / 1024,
539 iops / 100, iops % 100);
534 540
535 mmc_test_save_transfer_result(test, 1, sectors, ts, rate); 541 mmc_test_save_transfer_result(test, 1, sectors, ts, rate, iops);
536} 542}
537 543
538/* 544/*
@@ -542,22 +548,24 @@ static void mmc_test_print_avg_rate(struct mmc_test_card *test, uint64_t bytes,
542 unsigned int count, struct timespec *ts1, 548 unsigned int count, struct timespec *ts1,
543 struct timespec *ts2) 549 struct timespec *ts2)
544{ 550{
545 unsigned int rate, sectors = bytes >> 9; 551 unsigned int rate, iops, sectors = bytes >> 9;
546 uint64_t tot = bytes * count; 552 uint64_t tot = bytes * count;
547 struct timespec ts; 553 struct timespec ts;
548 554
549 ts = timespec_sub(*ts2, *ts1); 555 ts = timespec_sub(*ts2, *ts1);
550 556
551 rate = mmc_test_rate(tot, &ts); 557 rate = mmc_test_rate(tot, &ts);
558 iops = mmc_test_rate(count * 100, &ts); /* I/O ops per sec x 100 */
552 559
553 printk(KERN_INFO "%s: Transfer of %u x %u sectors (%u x %u%s KiB) took " 560 printk(KERN_INFO "%s: Transfer of %u x %u sectors (%u x %u%s KiB) took "
554 "%lu.%09lu seconds (%u kB/s, %u KiB/s)\n", 561 "%lu.%09lu seconds (%u kB/s, %u KiB/s, "
562 "%u.%02u IOPS)\n",
555 mmc_hostname(test->card->host), count, sectors, count, 563 mmc_hostname(test->card->host), count, sectors, count,
556 sectors >> 1, (sectors & 1 ? ".5" : ""), 564 sectors >> 1, (sectors & 1 ? ".5" : ""),
557 (unsigned long)ts.tv_sec, (unsigned long)ts.tv_nsec, 565 (unsigned long)ts.tv_sec, (unsigned long)ts.tv_nsec,
558 rate / 1000, rate / 1024); 566 rate / 1000, rate / 1024, iops / 100, iops % 100);
559 567
560 mmc_test_save_transfer_result(test, count, sectors, ts, rate); 568 mmc_test_save_transfer_result(test, count, sectors, ts, rate, iops);
561} 569}
562 570
563/* 571/*
@@ -1425,28 +1433,29 @@ static int mmc_test_area_cleanup(struct mmc_test_card *test)
1425} 1433}
1426 1434
1427/* 1435/*
1428 * Initialize an area for testing large transfers. The size of the area is the 1436 * Initialize an area for testing large transfers. The test area is set to the
1429 * preferred erase size which is a good size for optimal transfer speed. Note 1437 * middle of the card because cards may have different charateristics at the
1430 * that is typically 4MiB for modern cards. The test area is set to the middle 1438 * front (for FAT file system optimization). Optionally, the area is erased
1431 * of the card because cards may have different charateristics at the front 1439 * (if the card supports it) which may improve write performance. Optionally,
1432 * (for FAT file system optimization). Optionally, the area is erased (if the 1440 * the area is filled with data for subsequent read tests.
1433 * card supports it) which may improve write performance. Optionally, the area
1434 * is filled with data for subsequent read tests.
1435 */ 1441 */
1436static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill) 1442static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill)
1437{ 1443{
1438 struct mmc_test_area *t = &test->area; 1444 struct mmc_test_area *t = &test->area;
1439 unsigned long min_sz = 64 * 1024; 1445 unsigned long min_sz = 64 * 1024, sz;
1440 int ret; 1446 int ret;
1441 1447
1442 ret = mmc_test_set_blksize(test, 512); 1448 ret = mmc_test_set_blksize(test, 512);
1443 if (ret) 1449 if (ret)
1444 return ret; 1450 return ret;
1445 1451
1446 if (test->card->pref_erase > TEST_AREA_MAX_SIZE >> 9) 1452 /* Make the test area size about 4MiB */
1447 t->max_sz = TEST_AREA_MAX_SIZE; 1453 sz = (unsigned long)test->card->pref_erase << 9;
1448 else 1454 t->max_sz = sz;
1449 t->max_sz = (unsigned long)test->card->pref_erase << 9; 1455 while (t->max_sz < 4 * 1024 * 1024)
1456 t->max_sz += sz;
1457 while (t->max_sz > TEST_AREA_MAX_SIZE && t->max_sz > sz)
1458 t->max_sz -= sz;
1450 1459
1451 t->max_segs = test->card->host->max_segs; 1460 t->max_segs = test->card->host->max_segs;
1452 t->max_seg_sz = test->card->host->max_seg_size; 1461 t->max_seg_sz = test->card->host->max_seg_size;
@@ -1766,6 +1775,188 @@ static int mmc_test_profile_seq_trim_perf(struct mmc_test_card *test)
1766 return 0; 1775 return 0;
1767} 1776}
1768 1777
1778static unsigned int rnd_next = 1;
1779
1780static unsigned int mmc_test_rnd_num(unsigned int rnd_cnt)
1781{
1782 uint64_t r;
1783
1784 rnd_next = rnd_next * 1103515245 + 12345;
1785 r = (rnd_next >> 16) & 0x7fff;
1786 return (r * rnd_cnt) >> 15;
1787}
1788
1789static int mmc_test_rnd_perf(struct mmc_test_card *test, int write, int print,
1790 unsigned long sz)
1791{
1792 unsigned int dev_addr, cnt, rnd_addr, range1, range2, last_ea = 0, ea;
1793 unsigned int ssz;
1794 struct timespec ts1, ts2, ts;
1795 int ret;
1796
1797 ssz = sz >> 9;
1798
1799 rnd_addr = mmc_test_capacity(test->card) / 4;
1800 range1 = rnd_addr / test->card->pref_erase;
1801 range2 = range1 / ssz;
1802
1803 getnstimeofday(&ts1);
1804 for (cnt = 0; cnt < UINT_MAX; cnt++) {
1805 getnstimeofday(&ts2);
1806 ts = timespec_sub(ts2, ts1);
1807 if (ts.tv_sec >= 10)
1808 break;
1809 ea = mmc_test_rnd_num(range1);
1810 if (ea == last_ea)
1811 ea -= 1;
1812 last_ea = ea;
1813 dev_addr = rnd_addr + test->card->pref_erase * ea +
1814 ssz * mmc_test_rnd_num(range2);
1815 ret = mmc_test_area_io(test, sz, dev_addr, write, 0, 0);
1816 if (ret)
1817 return ret;
1818 }
1819 if (print)
1820 mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
1821 return 0;
1822}
1823
1824static int mmc_test_random_perf(struct mmc_test_card *test, int write)
1825{
1826 unsigned int next;
1827 unsigned long sz;
1828 int ret;
1829
1830 for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
1831 /*
1832 * When writing, try to get more consistent results by running
1833 * the test twice with exactly the same I/O but outputting the
1834 * results only for the 2nd run.
1835 */
1836 if (write) {
1837 next = rnd_next;
1838 ret = mmc_test_rnd_perf(test, write, 0, sz);
1839 if (ret)
1840 return ret;
1841 rnd_next = next;
1842 }
1843 ret = mmc_test_rnd_perf(test, write, 1, sz);
1844 if (ret)
1845 return ret;
1846 }
1847 sz = test->area.max_tfr;
1848 if (write) {
1849 next = rnd_next;
1850 ret = mmc_test_rnd_perf(test, write, 0, sz);
1851 if (ret)
1852 return ret;
1853 rnd_next = next;
1854 }
1855 return mmc_test_rnd_perf(test, write, 1, sz);
1856}
1857
1858/*
1859 * Random read performance by transfer size.
1860 */
1861static int mmc_test_random_read_perf(struct mmc_test_card *test)
1862{
1863 return mmc_test_random_perf(test, 0);
1864}
1865
1866/*
1867 * Random write performance by transfer size.
1868 */
1869static int mmc_test_random_write_perf(struct mmc_test_card *test)
1870{
1871 return mmc_test_random_perf(test, 1);
1872}
1873
1874static int mmc_test_seq_perf(struct mmc_test_card *test, int write,
1875 unsigned int tot_sz, int max_scatter)
1876{
1877 unsigned int dev_addr, i, cnt, sz, ssz;
1878 struct timespec ts1, ts2, ts;
1879 int ret;
1880
1881 sz = test->area.max_tfr;
1882 /*
1883 * In the case of a maximally scattered transfer, the maximum transfer
1884 * size is further limited by using PAGE_SIZE segments.
1885 */
1886 if (max_scatter) {
1887 struct mmc_test_area *t = &test->area;
1888 unsigned long max_tfr;
1889
1890 if (t->max_seg_sz >= PAGE_SIZE)
1891 max_tfr = t->max_segs * PAGE_SIZE;
1892 else
1893 max_tfr = t->max_segs * t->max_seg_sz;
1894 if (sz > max_tfr)
1895 sz = max_tfr;
1896 }
1897
1898 ssz = sz >> 9;
1899 dev_addr = mmc_test_capacity(test->card) / 4;
1900 if (tot_sz > dev_addr << 9)
1901 tot_sz = dev_addr << 9;
1902 cnt = tot_sz / sz;
1903 dev_addr &= 0xffff0000; /* Round to 64MiB boundary */
1904
1905 getnstimeofday(&ts1);
1906 for (i = 0; i < cnt; i++) {
1907 ret = mmc_test_area_io(test, sz, dev_addr, write,
1908 max_scatter, 0);
1909 if (ret)
1910 return ret;
1911 dev_addr += ssz;
1912 }
1913 getnstimeofday(&ts2);
1914
1915 ts = timespec_sub(ts2, ts1);
1916 mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
1917
1918 return 0;
1919}
1920
1921static int mmc_test_large_seq_perf(struct mmc_test_card *test, int write)
1922{
1923 int ret, i;
1924
1925 for (i = 0; i < 10; i++) {
1926 ret = mmc_test_seq_perf(test, write, 10 * 1024 * 1024, 1);
1927 if (ret)
1928 return ret;
1929 }
1930 for (i = 0; i < 5; i++) {
1931 ret = mmc_test_seq_perf(test, write, 100 * 1024 * 1024, 1);
1932 if (ret)
1933 return ret;
1934 }
1935 for (i = 0; i < 3; i++) {
1936 ret = mmc_test_seq_perf(test, write, 1000 * 1024 * 1024, 1);
1937 if (ret)
1938 return ret;
1939 }
1940
1941 return ret;
1942}
1943
1944/*
1945 * Large sequential read performance.
1946 */
1947static int mmc_test_large_seq_read_perf(struct mmc_test_card *test)
1948{
1949 return mmc_test_large_seq_perf(test, 0);
1950}
1951
1952/*
1953 * Large sequential write performance.
1954 */
1955static int mmc_test_large_seq_write_perf(struct mmc_test_card *test)
1956{
1957 return mmc_test_large_seq_perf(test, 1);
1958}
1959
1769static const struct mmc_test_case mmc_test_cases[] = { 1960static const struct mmc_test_case mmc_test_cases[] = {
1770 { 1961 {
1771 .name = "Basic write (no data verification)", 1962 .name = "Basic write (no data verification)",
@@ -2005,6 +2196,34 @@ static const struct mmc_test_case mmc_test_cases[] = {
2005 .cleanup = mmc_test_area_cleanup, 2196 .cleanup = mmc_test_area_cleanup,
2006 }, 2197 },
2007 2198
2199 {
2200 .name = "Random read performance by transfer size",
2201 .prepare = mmc_test_area_prepare,
2202 .run = mmc_test_random_read_perf,
2203 .cleanup = mmc_test_area_cleanup,
2204 },
2205
2206 {
2207 .name = "Random write performance by transfer size",
2208 .prepare = mmc_test_area_prepare,
2209 .run = mmc_test_random_write_perf,
2210 .cleanup = mmc_test_area_cleanup,
2211 },
2212
2213 {
2214 .name = "Large sequential read into scattered pages",
2215 .prepare = mmc_test_area_prepare,
2216 .run = mmc_test_large_seq_read_perf,
2217 .cleanup = mmc_test_area_cleanup,
2218 },
2219
2220 {
2221 .name = "Large sequential write from scattered pages",
2222 .prepare = mmc_test_area_prepare,
2223 .run = mmc_test_large_seq_write_perf,
2224 .cleanup = mmc_test_area_cleanup,
2225 },
2226
2008}; 2227};
2009 2228
2010static DEFINE_MUTEX(mmc_test_lock); 2229static DEFINE_MUTEX(mmc_test_lock);
@@ -2148,11 +2367,11 @@ static int mtf_test_show(struct seq_file *sf, void *data)
2148 seq_printf(sf, "Test %d: %d\n", gr->testcase + 1, gr->result); 2367 seq_printf(sf, "Test %d: %d\n", gr->testcase + 1, gr->result);
2149 2368
2150 list_for_each_entry(tr, &gr->tr_lst, link) { 2369 list_for_each_entry(tr, &gr->tr_lst, link) {
2151 seq_printf(sf, "%u %d %lu.%09lu %u\n", 2370 seq_printf(sf, "%u %d %lu.%09lu %u %u.%02u\n",
2152 tr->count, tr->sectors, 2371 tr->count, tr->sectors,
2153 (unsigned long)tr->ts.tv_sec, 2372 (unsigned long)tr->ts.tv_sec,
2154 (unsigned long)tr->ts.tv_nsec, 2373 (unsigned long)tr->ts.tv_nsec,
2155 tr->rate); 2374 tr->rate, tr->iops / 100, tr->iops % 100);
2156 } 2375 }
2157 } 2376 }
2158 2377