From patchwork Sun Aug 26 12:06:45 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 180047 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from merlin.infradead.org (unknown [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 7F81F2C00E7 for ; Sun, 26 Aug 2012 22:08:33 +1000 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1T5bd3-00081j-Pk; Sun, 26 Aug 2012 12:07:45 +0000 Received: from mail-pz0-f49.google.com ([209.85.210.49]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1T5bcn-0007yb-PU for linux-mtd@lists.infradead.org; Sun, 26 Aug 2012 12:07:30 +0000 Received: by dajq27 with SMTP id q27so1923572daj.36 for ; Sun, 26 Aug 2012 05:07:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=D9aMkh8g72LmWGjfNZomSXyOUjJ6DIlwpkG1sO1/vN0=; b=n4GAwA16zOAp1dxJWmm4olfs28HjQTZ9dz8qA2FYo3hL1fJ2uxiPrWNq8HXgp5L8vv 4ErdYjoNXDI/4iqYjkUam7Qm0lBRTHwnx2aC8B+qn574N2yr71Trim8uopKFee51MQT/ YPOZlOoTdNIM0Jm0vukkt1Es9bo1t36iFebXybec71uswpZKDFxuMsqIDNlE53Xf7Vuh VXnmwx/eg/knK4gLIhorg51/5NkpdyPc/bMMgXwXKkUI1uz0TYRX4Q4pYOpkBZiVaTwZ qXXCyv0avxuhgwJsPn62XDgTedsrbNzLt3EFM1G3sJyxR09/rlo111itsPNKo5wNVTVu aXDQ== Received: by 10.68.224.161 with SMTP id rd1mr26940766pbc.133.1345982848976; Sun, 26 Aug 2012 05:07:28 -0700 (PDT) Received: from localhost.localdomain (p4038-ipngn701hodogaya.kanagawa.ocn.ne.jp. [114.158.195.38]) by mx.google.com with ESMTPS id uj3sm12422743pbc.39.2012.08.26.05.07.27 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 26 Aug 2012 05:07:28 -0700 (PDT) From: Akinobu Mita To: linux-mtd@lists.infradead.org Subject: [PATCH v2 3/6] mtd: mtd_nandecctest: rewrite the test routine Date: Sun, 26 Aug 2012 21:06:45 +0900 Message-Id: <1345982808-11440-4-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 1.7.11.4 In-Reply-To: <1345982808-11440-1-git-send-email-akinobu.mita@gmail.com> References: <1345982808-11440-1-git-send-email-akinobu.mita@gmail.com> X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.7 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.210.49 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (akinobu.mita[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: Artem Bityutskiy , David Woodhouse , Akinobu Mita X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This rewrites the entire test routine in order to make it easy to add more tests by later changes and minimize duplication of each tests as much as possible. Signed-off-by: Akinobu Mita Cc: David Woodhouse Cc: linux-mtd@lists.infradead.org Cc: Artem Bityutskiy --- drivers/mtd/tests/mtd_nandecctest.c | 136 +++++++++++++++++++++++++++--------- 1 file changed, 104 insertions(+), 32 deletions(-) diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c index f71ed92..466bc5c 100644 --- a/drivers/mtd/tests/mtd_nandecctest.c +++ b/drivers/mtd/tests/mtd_nandecctest.c @@ -5,59 +5,131 @@ #include #include #include +#include #include +#include + #if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE) -static void inject_single_bit_error(void *data, size_t size) +struct nand_ecc_test { + const char *name; + void (*prepare)(void *, void *, void *, void *, const size_t); + int (*verify)(void *, void *, void *, const size_t); +}; + +#ifdef __LITTLE_ENDIAN +#define __change_bit_le(nr, addr) __change_bit(nr, addr) +#else +#define __change_bit_le(nr, addr) \ + __change_bit((nr) ^ ((BITS_PER_LONG - 1) & ~0x7), addr) +#endif + +static void single_bit_error_data(void *error_data, void *correct_data, + size_t size) { - unsigned long offset = random32() % (size * BITS_PER_BYTE); + unsigned int offset = random32() % (size * BITS_PER_BYTE); - __change_bit(offset, data); + memcpy(error_data, correct_data, size); + __change_bit_le(offset, error_data); } -static unsigned char data[512]; -static unsigned char error_data[512]; +static void single_bit_error_in_data(void *error_data, void *error_ecc, + void *correct_data, void *correct_ecc, const size_t size) +{ + single_bit_error_data(error_data, correct_data, size); + memcpy(error_ecc, correct_ecc, 3); +} -static int nand_ecc_test(const size_t size) +static int single_bit_error_correct(void *error_data, void *error_ecc, + void *correct_data, const size_t size) { - unsigned char code[3]; - unsigned char error_code[3]; - char testname[30]; + unsigned char calc_ecc[3]; + int ret; + + __nand_calculate_ecc(error_data, size, calc_ecc); + ret = __nand_correct_data(error_data, calc_ecc, error_ecc, size); + if (ret == 1 && !memcmp(correct_data, error_data, size)) + return 0; - BUG_ON(sizeof(data) < size); + return -EINVAL; +} - sprintf(testname, "nand-ecc-%zu", size); +static const struct nand_ecc_test nand_ecc_test[] = { + { + .name = "single-bit-error-in-data-correct", + .prepare = single_bit_error_in_data, + .verify = single_bit_error_correct, + }, +}; - get_random_bytes(data, size); +static void dump_data_ecc(void *error_data, void *error_ecc, void *correct_data, + void *correct_ecc, const size_t size) +{ + pr_info("hexdump of error data:\n"); + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4, + error_data, size, false); + print_hex_dump(KERN_INFO, "hexdump of error ecc: ", + DUMP_PREFIX_NONE, 16, 1, error_ecc, 3, false); - memcpy(error_data, data, size); - inject_single_bit_error(error_data, size); + pr_info("hexdump of correct data:\n"); + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4, + correct_data, size, false); + print_hex_dump(KERN_INFO, "hexdump of correct ecc: ", + DUMP_PREFIX_NONE, 16, 1, correct_ecc, 3, false); - __nand_calculate_ecc(data, size, code); - __nand_calculate_ecc(error_data, size, error_code); - __nand_correct_data(error_data, code, error_code, size); +} - if (!memcmp(data, error_data, size)) { - printk(KERN_INFO "mtd_nandecctest: ok - %s\n", testname); - return 0; +static int nand_ecc_test_run(const size_t size) +{ + int i; + int err = 0; + void *error_data; + void *error_ecc; + void *correct_data; + void *correct_ecc; + + error_data = kmalloc(size, GFP_KERNEL); + error_ecc = kmalloc(3, GFP_KERNEL); + correct_data = kmalloc(size, GFP_KERNEL); + correct_ecc = kmalloc(3, GFP_KERNEL); + + if (!error_data || !error_ecc || !correct_data || !correct_ecc) { + err = -ENOMEM; + goto error; } - printk(KERN_ERR "mtd_nandecctest: not ok - %s\n", testname); - - printk(KERN_DEBUG "hexdump of data:\n"); - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, - data, size, false); - printk(KERN_DEBUG "hexdump of error data:\n"); - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, - error_data, size, false); + get_random_bytes(correct_data, size); + __nand_calculate_ecc(correct_data, size, correct_ecc); + + for (i = 0; i < ARRAY_SIZE(nand_ecc_test); i++) { + nand_ecc_test[i].prepare(error_data, error_ecc, + correct_data, correct_ecc, size); + err = nand_ecc_test[i].verify(error_data, error_ecc, + correct_data, size); + + if (err) { + pr_err("mtd_nandecctest: not ok - %s-%zd\n", + nand_ecc_test[i].name, size); + dump_data_ecc(error_data, error_ecc, + correct_data, correct_ecc, size); + break; + } + pr_info("mtd_nandecctest: ok - %s-%zd\n", + nand_ecc_test[i].name, size); + } +error: + kfree(error_data); + kfree(error_ecc); + kfree(correct_data); + kfree(correct_ecc); - return -1; + return err; } #else -static int nand_ecc_test(const size_t size) +static int nand_ecc_test_run(const size_t size) { return 0; } @@ -68,11 +140,11 @@ static int __init ecc_test_init(void) { int err; - err = nand_ecc_test(256); + err = nand_ecc_test_run(256); if (err) return err; - return nand_ecc_test(512); + return nand_ecc_test_run(512); } static void __exit ecc_test_exit(void)