diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2011-07-01 13:05:06 +0000 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2011-07-01 13:05:06 +0000 |
commit | 03d210895f393b6eba617ac945a729f70c7101a4 (patch) | |
tree | 78f31959961ce5cbd000d1a5640834589a527164 /c/src/lib/libbsp/arm/lpc32xx/misc | |
parent | Fix. (diff) | |
download | rtems-03d210895f393b6eba617ac945a729f70c7101a4.tar.bz2 |
2011-07-01 Stephan Hoffmann <sho@reLinux.de>
Sebastian Huber <sebastian.huber@embedded-brains.de>
* misc/nand-mlc-erase-block-safe.c: New file
* Makefile.am: Reflect change from above.
* misc/nand-mlc-write-blocks.c: Use lpc32xx_mlc_erase_block_safe_3().
* include/nand-mlc.h: Bad block handling.
Diffstat (limited to 'c/src/lib/libbsp/arm/lpc32xx/misc')
-rw-r--r-- | c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-erase-block-safe.c | 94 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-write-blocks.c | 78 |
2 files changed, 106 insertions, 66 deletions
diff --git a/c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-erase-block-safe.c b/c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-erase-block-safe.c new file mode 100644 index 0000000000..e7b49f58e7 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-erase-block-safe.c @@ -0,0 +1,94 @@ +/** + * @file + * + * @ingroup lpc32xx_nand_mlc + * + * @brief lpc32xx_mlc_erase_block_safe() and lpc32xx_mlc_erase_block_safe_3() + * implementation. + */ + +/* + * Copyright (c) 2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include <bsp/nand-mlc.h> + +#include <string.h> + +#include <bsp.h> + +static void zero_block(uint32_t first_page_of_block, uint32_t pages_per_block) +{ + uint32_t page = 0; + + for (page = 0; page < pages_per_block; ++page) { + lpc32xx_mlc_write_page_with_ecc( + first_page_of_block + page, + lpc32xx_magic_zero_begin, + lpc32xx_magic_zero_begin + ); + } +} + +static bool is_bad_page( + uint32_t first_page_of_block, + uint32_t page +) +{ + uint32_t spare [MLC_LARGE_SPARE_WORD_COUNT]; + + memset(spare, 0, MLC_LARGE_SPARE_SIZE); + lpc32xx_mlc_read_page( + first_page_of_block + page, + lpc32xx_magic_zero_begin, + spare + ); + return lpc32xx_mlc_is_bad_page(spare); +} + +rtems_status_code lpc32xx_mlc_erase_block_safe_3( + uint32_t block_index, + uint32_t first_page_of_block, + uint32_t pages_per_block +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + if (is_bad_page(first_page_of_block, 0)) { + return RTEMS_INCORRECT_STATE; + } + + if (is_bad_page(first_page_of_block, 1)) { + return RTEMS_INCORRECT_STATE; + } + + sc = lpc32xx_mlc_erase_block(block_index); + if (sc != RTEMS_SUCCESSFUL) { + zero_block(first_page_of_block, pages_per_block); + + return RTEMS_IO_ERROR; + } + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code lpc32xx_mlc_erase_block_safe(uint32_t block_index) +{ + uint32_t pages_per_block = lpc32xx_mlc_pages_per_block(); + + return lpc32xx_mlc_erase_block_safe_3( + block_index, + block_index * pages_per_block, + pages_per_block + ); +} diff --git a/c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-write-blocks.c b/c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-write-blocks.c index 8b9c438602..b95c9e1399 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-write-blocks.c +++ b/c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-write-blocks.c @@ -7,12 +7,13 @@ */ /* - * Copyright (c) 2010 - * embedded brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * <rtems@embedded-brains.de> + * Copyright (c) 2010-2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -21,10 +22,6 @@ #include <bsp/nand-mlc.h> -#include <string.h> - -#include <bsp.h> - static const uint32_t ones_spare [MLC_LARGE_SPARE_WORD_COUNT] = { 0xffffffff, 0xffffffff, @@ -44,61 +41,6 @@ static const uint32_t ones_spare [MLC_LARGE_SPARE_WORD_COUNT] = { 0xffffffff }; -static void zero_block(uint32_t first_page_of_block, uint32_t pages_per_block) -{ - uint32_t page = 0; - - for (page = 0; page < pages_per_block; ++page) { - lpc32xx_mlc_write_page_with_ecc( - first_page_of_block + page, - lpc32xx_magic_zero_begin, - lpc32xx_magic_zero_begin - ); - } -} - -static bool is_bad_page( - uint32_t first_page_of_block, - uint32_t page -) -{ - uint32_t spare [MLC_LARGE_SPARE_WORD_COUNT]; - - memset(spare, 0, MLC_LARGE_SPARE_SIZE); - lpc32xx_mlc_read_page( - first_page_of_block + page, - lpc32xx_magic_zero_begin, - spare - ); - return lpc32xx_mlc_is_bad_page(spare); -} - -static rtems_status_code erase_block( - uint32_t block, - uint32_t first_page_of_block, - uint32_t pages_per_block -) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - - if (is_bad_page(first_page_of_block, 0)) { - return RTEMS_IO_ERROR; - } - - if (is_bad_page(first_page_of_block, 1)) { - return RTEMS_IO_ERROR; - } - - sc = lpc32xx_mlc_erase_block(block); - if (sc != RTEMS_SUCCESSFUL) { - zero_block(first_page_of_block, pages_per_block); - - return RTEMS_IO_ERROR; - } - - return RTEMS_SUCCESSFUL; -} - rtems_status_code lpc32xx_mlc_write_blocks( uint32_t block_begin, uint32_t block_end, @@ -124,7 +66,11 @@ rtems_status_code lpc32xx_mlc_write_blocks( uint32_t first_page_of_block = block * pages_per_block; uint32_t page = 0; - sc = erase_block(block, first_page_of_block, pages_per_block); + sc = lpc32xx_mlc_erase_block_safe_3( + block, + first_page_of_block, + pages_per_block + ); if (sc != RTEMS_SUCCESSFUL) { continue; } |