From 6ccd7242c4c1404dafb64cd937adc3c65ce02385 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 21 Jun 2006 14:26:02 +0200 Subject: [MTD] UBI: Removed automake, autoconf, added ubi userspace headers. Signed-off-by: Frank Haverkamp --- ubi-utils/src/nandcorr.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 ubi-utils/src/nandcorr.c (limited to 'ubi-utils/src/nandcorr.c') diff --git a/ubi-utils/src/nandcorr.c b/ubi-utils/src/nandcorr.c new file mode 100644 index 0000000..7f1a547 --- /dev/null +++ b/ubi-utils/src/nandcorr.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * ECC algorithm for NAND FLASH. Detects and corrects 1 bit errors in + * a 256 bytes of data. + * + * Reimplement by Thomas Gleixner after staring long enough at the + * mess in drivers/mtd/nand/nandecc.c + * + */ + +#include "nandecc.h" + +static int countbits(uint32_t byte) +{ + int res = 0; + + for (;byte; byte >>= 1) + res += byte & 0x01; + return res; +} + +int nand_correct_data(uint8_t *dat, const uint8_t *fail_ecc) + +{ + uint8_t s0, s1, s2; + + /* + * Do error detection + * + * Be careful, the index magic is due to a pointer to a + * uint32_t. + */ + s0 = fail_ecc[1]; + s1 = fail_ecc[2]; + s2 = fail_ecc[3]; + + /* Check for a single bit error */ + if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 && + ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 && + ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) { + + uint32_t byteoffs, bitnum; + + byteoffs = (s1 << 0) & 0x80; + byteoffs |= (s1 << 1) & 0x40; + byteoffs |= (s1 << 2) & 0x20; + byteoffs |= (s1 << 3) & 0x10; + + byteoffs |= (s0 >> 4) & 0x08; + byteoffs |= (s0 >> 3) & 0x04; + byteoffs |= (s0 >> 2) & 0x02; + byteoffs |= (s0 >> 1) & 0x01; + + bitnum = (s2 >> 5) & 0x04; + bitnum |= (s2 >> 4) & 0x02; + bitnum |= (s2 >> 3) & 0x01; + + dat[byteoffs] ^= (1 << bitnum); + + return 1; + } + + if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1) + return 1; + + return -1; +} + -- cgit v1.2.3