public inbox for ecos-patches@sourceware.org
 help / color / mirror / Atom feed
* NAND Flash device driver
@ 2007-12-10 13:01 Alexey Shusharin
  2007-12-18  4:02 ` Alexey Shusharin
  0 siblings, 1 reply; 10+ messages in thread
From: Alexey Shusharin @ 2007-12-10 13:01 UTC (permalink / raw)
  To: ecos-patches

[-- Attachment #1: Type: text/plain, Size: 281 bytes --]

Hi,

This patch adds a NAND Flash device driver to flash V1 branch.

Currently it supports 8-bit NAND flash with 256/512 page size and has
implemented software ECC and simple bad block management algorithms.

I've tested it with SAMSUNG K9F5608U0D.

Best regards
Alexey Shusharin


[-- Attachment #2: nand.patch --]
[-- Type: text/x-patch, Size: 71458 bytes --]

diff -bur -P /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/cdl/nand_flash.cdl ./devs/flash/nand/current/cdl/nand_flash.cdl
--- /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/cdl/nand_flash.cdl	1970-01-01 06:00:00.000000000 +0600
+++ ./devs/flash/nand/current/cdl/nand_flash.cdl	2007-12-10 18:31:58.000000000 +0600
@@ -0,0 +1,152 @@
+# ====================================================================
+#
+#      nand_flash.cdl
+#
+#      FLASH memory - Support for NAND flash
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## eCos 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 or (at your option) any later version.
+##
+## eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      Alexey Shusharin <mrfinch@mail.ru>
+# Contributors:   
+# Date:           2007-11-16
+# Description:    Driver for NAND FLASH devices.
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_NAND {
+    display       "NAND FLASH memory support"
+    description   "NAND FLASH memory device support"
+    parent        CYGPKG_IO_FLASH
+    active_if	  CYGPKG_IO_FLASH
+    
+    requires      { CYGSEM_IO_FLASH_READ_INDIRECT == 1 }
+    active_if     CYGINT_DEVS_FLASH_NAND_REQUIRED
+
+	compile       nand_flash.c
+
+    include_dir   cyg/io
+    
+    # Error checking and correction
+    cdl_component CYGPKG_DEVS_FLASH_NAND_ECC {
+        display       "Error checking and correction (ECC)"
+        flavor        none
+        description   "
+             NAND devices are subject to data failures that occur during
+             device operation. To ensure data read/write integrity, system
+             error checking and correction (ECC) algorithms should be
+             implemented. This component defines the using of ECC."
+        
+        cdl_interface CYGINT_DEVS_FLASH_NAND_ECC {
+            display  "Number of ECC variants in this configuration"
+            no_define
+            requires 1 == CYGINT_DEVS_FLASH_NAND_ECC
+        }
+        
+        cdl_option CYGSEM_DEVS_FLASH_NAND_ECC_OFF {
+            display       "No ECC algorithm"
+            default_value 0
+            implements    CYGINT_DEVS_FLASH_NAND_ECC
+            description   "
+                Don't use error checking and correction algorithm."
+        }
+        
+        cdl_option CYGSEM_DEVS_FLASH_NAND_ECC_SOFT {
+            display       "Software ECC algorithm"
+            default_value 1
+            implements    CYGINT_DEVS_FLASH_NAND_ECC
+            description   "
+                Use software error checking and correction algorithm which is
+                capable of single bit error correction and 2-bit random detection."
+        }
+    }
+    
+    # Bad block management
+    cdl_component CYGPKG_DEVS_FLASH_NAND_BLOCKMANAGE {
+        display       "Bad block management"
+        flavor        none
+        description   "
+             The NAND Flash devices may contain bad blocks, that shouldn't be
+             used. Additional bad blocks may develop during the lifetime
+             of the device. These blocks need to be managed using bad blocks
+             management. This component defines bad block management algorithm."
+        
+        cdl_interface CYGINT_DEVS_FLASH_NAND_BLOCKMANAGE {
+            display  "Number of bad block management algorithms in this configuration"
+            no_define
+            requires 1 == CYGINT_DEVS_FLASH_NAND_BLOCKMANAGE
+        }
+        
+        cdl_option CYGSEM_DEVS_FLASH_NAND_BBM_INIT {
+            display       "Initial bad blocks management"
+            default_value 0
+            implements    CYGINT_DEVS_FLASH_NAND_BLOCKMANAGE
+            description   "
+                Check only manufacturer marked bad blocks. NAND driver will
+                return error if application try to read/write/erase these blocks."
+        }
+        
+        cdl_component CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR {
+            display       "Bad blocks management with repair area"
+            default_value 1
+            implements    CYGINT_DEVS_FLASH_NAND_BLOCKMANAGE
+            description   "
+                Simple bad block management. NAND driver reserves repair
+                area at the end of the flash and replace bad blocks in main
+                area with blocks from it. New bad blocks will be also replaced.
+                Management information resides in last not bad block."
+                
+            cdl_option CYGNUM_DEVS_FLASH_NAND_BBM_REPAIR_SIZE {
+                display       "Repair area blocks count"
+                flavor        data
+                default_value 32
+                description   "
+                    Number of blocks in repair area. Usually it's equal 3%
+                    of whole flash."
+            }
+        }
+    }
+    
+    cdl_option CYGNUM_DEVS_FLASH_NAND_BUFFER_SIZE {
+        display       "Size of buffer"
+        flavor        data
+        default_value 1024
+        description   "
+            Size of statically linked buffer. It is used for page data and
+            spare area buffer, for bad block table and etc."
+    }
+}
+
+# EOF nand_flash.cdl
diff -bur -P /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/ChangeLog ./devs/flash/nand/current/ChangeLog
--- /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/ChangeLog	1970-01-01 06:00:00.000000000 +0600
+++ ./devs/flash/nand/current/ChangeLog	2007-12-10 16:59:41.000000000 +0600
@@ -0,0 +1,43 @@
+2007-12-10  Alexey Shusharin <mrfinch@mail.ru>
+
+    * NAND Flash driver package created
+    * cdl/nand_flash.cdl
+    * doc/nand_flash.sgml
+    * include/nand_flash.h
+    * src/nand_flash_parts.inl
+    * src/nand_flash.c
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff -bur -P /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/doc/nand_flash.sgml ./devs/flash/nand/current/doc/nand_flash.sgml
--- /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/doc/nand_flash.sgml	1970-01-01 06:00:00.000000000 +0600
+++ ./devs/flash/nand/current/doc/nand_flash.sgml	2007-12-10 16:58:46.000000000 +0600
@@ -0,0 +1,297 @@
+<!-- {{{ Banner                         -->
+
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!--     nand_flash.sgml                                             -->
+<!--                                                                 -->
+<!--     NAND Flash driver documentation.                            -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN####                                          -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004 eCosCentric Limited                          -->
+<!-- This material may be distributed only subject to the terms      -->
+<!-- and conditions set forth in the Open Publication License, v1.0  -->
+<!-- or later (the latest version is presently available at          -->
+<!-- http://www.opencontent.org/openpub/)                            -->
+<!-- Distribution of the work or derivative of the work in any       -->
+<!-- standard (paper) book form is prohibited unless prior           -->
+<!-- permission obtained from the copyright holder                   -->
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!-- ####COPYRIGHTEND####                                            -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN####                                       -->
+<!--                                                                 -->
+<!-- Author(s):   Alexey Shusharin                                   -->
+<!-- Date:        2007/12/10                                         -->
+<!--                                                                 -->
+<!-- ####DESCRIPTIONEND####                                          -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<PART id="devs-flash-nand"><title>NAND Flash Device Driver</title>
+
+<CHAPTER id="devs-flash-nand-support">
+<TITLE>Generic NAND Flash Device Driver</TITLE>
+
+<SECTION id="devs-flash-nand-support-overview">
+<TITLE>Overview</TITLE>
+
+<PARA>
+Generic NAND Flash driver feature:
+
+<variablelist>
+   <varlistentry>
+       <listitem><para>
+           - 8-bit NAND Flash devices with 256/512 page size support;
+       </para></listitem>
+       
+       <listitem><para>
+           - error checking and correction algorithm support;
+       </para></listitem>
+       
+       <listitem><para>
+           - bad block management support.
+       </para></listitem>
+   </varlistentry>
+</variablelist>
+
+</PARA>
+
+<PARA>
+    This driver is not compatible with Linux NAND Flash driver.
+    So if you use RedBoot to load Linux kernel, you cannot share
+    NAND Flash device with Linux.
+</PARA>
+
+</SECTION>
+
+<SECTION id="devs-flash-nand-support-config">
+<TITLE>Configuration options</TITLE>
+
+<PARA>
+Generic NAND Flash Device Driver has a number of configuration options.
+</PARA>
+
+<SECTION>
+<TITLE>cdl_component CYGPKG_DEVS_FLASH_NAND_ECC</TITLE>
+
+<PARA>
+    NAND devices are subject to data failures that occur during
+    device operation. To ensure data read/write integrity, system
+    error checking and correction (ECC) algorithms should be
+    implemented. This component defines the using of ECC.
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cdl_option CYGSEM_DEVS_FLASH_NAND_ECC_OFF</type></term>
+           <listitem><para>
+               Don't use error checking and correction algorithm.
+           </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGSEM_DEVS_FLASH_NAND_ECC_SOFT</type></term>
+           <listitem><para>
+               Use software error checking and correction algorithm which is
+               capable of single bit error correction and 2-bit random detection.
+           </para></listitem>
+   </varlistentry>
+</variablelist>
+
+</SECTION>
+
+<SECTION>
+<TITLE>cdl_component CYGPKG_DEVS_FLASH_NAND_BLOCKMANAGE</TITLE>
+
+<PARA>
+    The NAND Flash devices may contain bad blocks, that shouldn't be
+    used. Additional bad blocks may develop during the lifetime
+    of the device. These blocks need to be managed using bad blocks
+    management. This component defines bad block management algorithm.
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cdl_option CYGSEM_DEVS_FLASH_NAND_BBM_INIT</type></term>
+           <listitem><para>
+               Check only manufacturer marked bad blocks. NAND driver will
+               return error if application try to read/write/erase these blocks.
+           </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_component CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR</type></term>
+           <listitem><para>
+               Simple bad block management. NAND driver reserves repair
+               area at the end of the flash and replace bad blocks in main
+               area with blocks from it. New bad blocks will be also replaced.
+               Management information resides in last not bad block.
+           </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGNUM_DEVS_FLASH_NAND_BBM_REPAIR_SIZE</type></term>
+           <listitem><para>
+               Number of blocks in repair area. Usually it's equal 3%
+               of whole flash.
+           </para></listitem>
+   </varlistentry>
+</variablelist>
+
+</SECTION>
+</SECTION>
+
+<SECTION id="devs-flash-nand-support-platform">
+<TITLE>Platform driver template</TITLE>
+
+<PARA>
+NAND Flash support is specific to a platform. Hence you should create a
+package with platform specific code. This is a template of such package.
+</PARA>
+
+<SECTION>
+<TITLE>Configuration file</TITLE>
+
+<PROGRAMLISTING> 
+cdl_package CYGPKG_DEVS_FLASH_YOUR_PLATFORM {
+    display       "YOUR PLATFORM NAND FLASH memory support"
+    description   "NAND FLASH memory device support for ..."
+
+    include_dir   cyg/io
+
+    parent        CYGPKG_IO_FLASH
+    active_if     CYGPKG_IO_FLASH
+
+	define_proc {
+        puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_NAND_PLF_INL &lt;cyg/io/devs_flash_your_platform.inl&gt;"
+    }
+
+    cdl_interface CYGINT_DEVS_FLASH_NAND_REQUIRED {
+        display   "NAND FLASH driver required"
+    }
+
+    implements    CYGINT_DEVS_FLASH_NAND_REQUIRED
+    implements    CYGHWR_IO_FLASH_DEVICE
+}
+</PROGRAMLISTING>
+
+</SECTION>
+
+
+<SECTION>
+<TITLE>Source code file</TITLE>
+
+<PROGRAMLISTING> 
+#include &lt;cyg/hal/your_platform_misc.h&gt;
+
+//--------------------------------------------------------------------------
+// Platform specific access to control-lines
+//--------------------------------------------------------------------------
+
+#define CYGHWR_FLASH_NAND_PLF_INIT      nand_plf_init
+#define CYGHWR_FLASH_NAND_PLF_CE        nand_plf_ce
+#define CYGHWR_FLASH_NAND_PLF_WP        nand_plf_wp
+#define CYGHWR_FLASH_NAND_PLF_CMD       nand_plf_cmd
+#define CYGHWR_FLASH_NAND_PLF_ADDR      nand_plf_addr
+#define CYGHWR_FLASH_NAND_PLF_WAIT      nand_plf_wait
+
+//--------------------------------------------------------------------------
+// Global variables
+//--------------------------------------------------------------------------
+
+// The device-specific data
+static cyg_nand_dev nand_device = 
+{
+    .flash_base         = (void*) YOUR_PLATFORM_FLASHBASE,
+    .addr_r             = (void*) YOUR_PLATFORM_DATABASE,
+    .addr_w             = (void*) YOUR_PLATFORM_DATABASE,
+    
+    .delay_cmd          = 1,
+    .delay_rst          = 500,
+};
+
+//--------------------------------------------------------------------------
+// Init platform nand
+//--------------------------------------------------------------------------
+
+static inline void nand_plf_init(void)
+{
+    // Init NAND Flash platform stuff
+}
+
+//--------------------------------------------------------------------------
+// Enable/disable nand chip
+//--------------------------------------------------------------------------
+
+static inline void nand_plf_ce(int state)
+{
+    if(state)
+    {
+        // Enable CE line
+    }
+    else
+    {
+        // Disable CE line
+    }
+}
+
+//--------------------------------------------------------------------------
+// Enable/disable write protect
+//--------------------------------------------------------------------------
+
+static inline void nand_plf_wp(int nowrite)
+{
+    if(nowrite)
+    {
+        // Enable WP
+    }
+    else
+    {
+        // Disable WP
+    }
+}
+
+//--------------------------------------------------------------------------
+// Write nand command
+//--------------------------------------------------------------------------
+
+static inline void nand_plf_cmd(int cmd)
+{
+    // Enable CLE line
+    // Write command
+    // Disable CLE line
+}
+
+//--------------------------------------------------------------------------
+// Write nand address
+//--------------------------------------------------------------------------
+
+static inline void nand_plf_addr(int addr)
+{
+    // Enable ALE line
+    // Write address
+    // Disable ALE line
+}
+
+//--------------------------------------------------------------------------
+// Wait device ready pin
+//--------------------------------------------------------------------------
+
+static inline void nand_plf_wait(void)
+{
+    // Wait while device is not ready
+}
+
+//--------------------------------------------------------------------------
+</PROGRAMLISTING>
+
+</SECTION>
+
+
+</SECTION>
+
+</CHAPTER>
+
+</PART>
diff -bur -P /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/include/nand_flash.h ./devs/flash/nand/current/include/nand_flash.h
--- /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/include/nand_flash.h	1970-01-01 06:00:00.000000000 +0600
+++ ./devs/flash/nand/current/include/nand_flash.h	2007-12-07 20:05:52.000000000 +0600
@@ -0,0 +1,147 @@
+#ifndef _CYGONCE_FLASH_NAND_H_
+#define _CYGONCE_FLASH_NAND_H_
+//==========================================================================
+//
+//      nand_flash.h
+//
+//      FLASH memory - Support for NAND flash
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Alexey Shusharin <mrfinch@mail.ru>
+// Contributors: 
+// Date:         2007-11-16
+// Purpose:      
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/io/flash.h>
+
+#ifdef _FLASH_PRIVATE_
+
+//--------------------------------------------------------------------------
+// Defines
+
+#define NAND_REPAIR_SIZE    (CYGNUM_DEVS_FLASH_NAND_BBM_REPAIR_SIZE)
+
+//--------------------------------------------------------------------------
+// NAND flash commands
+
+typedef enum
+{
+    NAND_CMD_READ0      = 0x00,
+    NAND_CMD_READ1      = 0x01,
+    NAND_CMD_PAGEPROG   = 0x10,
+    NAND_CMD_READSPARE  = 0x50,
+    NAND_CMD_ERASE      = 0x60,
+    NAND_CMD_STATUS     = 0x70,
+    NAND_CMD_SEQIN      = 0x80,
+    NAND_CMD_READID     = 0x90,
+    NAND_CMD_ERASE2     = 0xD0,
+} cyg_nand_command;
+
+typedef enum
+{
+    NAND_STATUS_FAIL    = 0x01,
+    NAND_STATUS_READY   = 0x40,
+    NAND_STATUS_NOWP    = 0x80
+} cyg_nand_status;
+
+//--------------------------------------------------------------------------
+// 
+
+typedef struct cyg_nand_partinfo_st
+{
+    cyg_uint32  id;             // Device ID
+    
+    cyg_uint32  page_size;      // Page size in bytes.
+    
+    cyg_uint32  pages_count;    // Pages count in one block.
+    cyg_uint32  blocks_count;   // Blocks count in chip.
+    
+    cyg_uint32  options;        // Flash options
+    
+} cyg_nand_partinfo;
+
+//--------------------------------------------------------------------------
+// The device-specific data
+
+typedef struct cyg_nand_dev_st
+{
+    void*       flash_base;     // Flash base address
+    
+    void*       addr_r;         // Address to read data from flash
+    void*       addr_w;         // Address to write data to flash
+    
+    cyg_int32   delay_cmd;      // Delay after command or address (in micro-seconds)
+    cyg_int32   delay_rst;      // Delay after reset (in micro-seconds)
+    
+    //-------------------------------
+    
+    cyg_uint32  id;
+    
+    cyg_uint32  page_size;
+    cyg_uint32  spare_size;
+    
+    cyg_int32   pages_count;
+    cyg_int32   blocks_count;
+    
+    int         page_shift;
+    int         block_shift;
+    
+    cyg_uint8*  buf_data;       // Pointer to a data buffer
+    cyg_uint8*  buf_spare;      // Pointer to a spare buffer
+    cyg_uint8*  buf_bbt;        // Pointer to a bad block table
+    
+    cyg_int32   pageinbuf;      // Buffered page number (-1 if buffer is empty)
+    
+#if defined(CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR)
+    
+    cyg_uint32  bbm_info;       // Number of block with bbm info
+    cyg_int32   bbm_remap[NAND_REPAIR_SIZE];
+    
+#endif /*CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR*/
+    
+} cyg_nand_dev;
+
+#endif // _FLASH_PRIVATE_
+
+#endif // _CYGONCE_FLASH_NAND_H_
+//--------------------------------------------------------------------------
+// EOF nand_flash.h
diff -bur -P /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/src/nand_flash.c ./devs/flash/nand/current/src/nand_flash.c
--- /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/src/nand_flash.c	1970-01-01 06:00:00.000000000 +0600
+++ ./devs/flash/nand/current/src/nand_flash.c	2007-12-10 14:11:31.000000000 +0600
@@ -0,0 +1,1305 @@
+//==========================================================================
+//
+//      nand_flash.c
+//
+//      FLASH memory - Support for NAND flash
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Alexey Shusharin <mrfinch@mail.ru>
+// Contributors: 
+// Date:         2007-11-16
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_flash.h>
+#include <pkgconf/devs_flash_nand.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/infra/diag.h>
+
+#include <string.h>
+
+//--------------------------------------------------------------------------
+// Flash includes
+
+// This driver supports only one device and only 8-bit
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_WIDTH      (8)
+#define CYGNUM_FLASH_BLANK      (1)
+
+#define  _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+#include <cyg/io/nand_flash.h>
+
+//--------------------------------------------------------------------------
+// NAND driver debug level 
+//   0 - no debug message
+//   1 - only error messages
+//   2 - command level messages
+//   3 - hardware level messages
+
+#define NAND_DEBUG_LEVEL    1
+
+#if NAND_DEBUG_LEVEL == 3
+# define DEBUG_PRINT_ERR    flash_info.pf
+# define DEBUG_PRINT_CMD    flash_info.pf
+# define DEBUG_PRINT_HDW    flash_info.pf
+#elif NAND_DEBUG_LEVEL == 2
+# define DEBUG_PRINT_ERR    flash_info.pf
+# define DEBUG_PRINT_CMD    flash_info.pf
+# define DEBUG_PRINT_HDW(fmt, ...)
+#elif NAND_DEBUG_LEVEL == 1
+# define DEBUG_PRINT_ERR    flash_info.pf
+# define DEBUG_PRINT_CMD(fmt, ...)
+# define DEBUG_PRINT_HDW(fmt, ...)
+#else
+# define DEBUG_PRINT_ERR(fmt, ...)
+# define DEBUG_PRINT_CMD(fmt, ...)
+# define DEBUG_PRINT_HDW(fmt, ...)
+#endif
+
+//--------------------------------------------------------------------------
+// NAND data buffer
+static cyg_uint8 nand_buffer[CYGNUM_DEVS_FLASH_NAND_BUFFER_SIZE];
+
+#ifdef CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR
+// Repair managemment id string
+static const char nand_bbm_id[32] = "Repair management table v1.0";
+#endif
+
+//--------------------------------------------------------------------------
+// Include NAND FLASH parts
+#include "nand_flash_parts.inl"
+
+//--------------------------------------------------------------------------
+// Include platform NAND FLASH definitions
+#include CYGDAT_DEVS_FLASH_NAND_PLF_INL
+
+// These platform functions is not obligatory
+#ifndef CYGHWR_FLASH_NAND_PLF_INIT
+# define CYGHWR_FLASH_NAND_PLF_INIT()
+#endif
+#ifndef CYGHWR_FLASH_NAND_PLF_CE
+# define CYGHWR_FLASH_NAND_PLF_CE(state)
+#endif
+#ifndef CYGHWR_FLASH_NAND_PLF_WP
+# define CYGHWR_FLASH_NAND_PLF_WP(state)
+#endif
+
+//--------------------------------------------------------------------------
+// Auxiliary functions
+//--------------------------------------------------------------------------
+
+static int nand_ffs(cyg_uint32 data)
+{
+    int res = 1;
+    
+    if(!data) return 0;
+    
+    if(data > 0xFFFF) {res += 16; data >>= 16;}
+    if(data > 0xFF) {res += 8; data >>= 8;}
+    if(data > 0x0F) {res += 4; data >>= 4;}
+    if(data > 0x03) {res += 2; data >>= 2;}
+    if(data > 0x01) res += 1;
+    
+    return res;
+}
+
+//--------------------------------------------------------------------------
+// Hardware dependent functions
+//--------------------------------------------------------------------------
+
+static inline cyg_uint8 nand_read_byte(void)
+{
+    cyg_uint8 res;
+    
+    HAL_READ_UINT8(nand_device.addr_r, res);
+    
+    return res;
+}
+
+static inline void nand_read_buf(cyg_uint8* buf, cyg_uint32 len)
+{
+    cyg_uint32 i;
+    
+    for(i = 0; i < len; i++)
+    {
+        HAL_READ_UINT8(nand_device.addr_r, buf[i]);
+    }
+}
+
+static inline void nand_write_buf(cyg_uint8* buf, cyg_uint32 len)
+{
+    cyg_uint32 i;
+    
+    for(i = 0; i < len; i++)
+    {
+        HAL_WRITE_UINT8(nand_device.addr_w, buf[i]);
+    }
+}
+
+//--------------------------------------------------------------------------
+// ECC functions
+//--------------------------------------------------------------------------
+
+#if defined(CYGSEM_DEVS_FLASH_NAND_ECC_SOFT)
+
+static inline int nand_get_parity(int val)
+{
+    // Calc byte parity
+    val ^= (val >> 4);
+    val ^= (val >> 2);
+    val ^= (val >> 1);
+    
+    return val & 1;
+}
+
+static cyg_uint32 nand_calc_ecc(cyg_uint8* data)
+{
+    int p_col, p_8, p_16, p_32, p_hi, tmp, block;
+    cyg_uint32 ecc;
+    int i;
+    
+    p_col = p_8 = p_16 = p_32 = p_hi = 0;
+    
+    // Calc bits parity
+    for(i = 0; i < 32; i++)
+    {
+        block = *data++;
+        tmp = *data++; block ^= tmp; p_8 ^= tmp;
+        tmp = *data++; block ^= tmp;             p_16 ^= tmp;
+        tmp = *data++; block ^= tmp; p_8 ^= tmp; p_16 ^= tmp;
+        tmp = *data++; block ^= tmp;                          p_32 ^= tmp;
+        tmp = *data++; block ^= tmp; p_8 ^= tmp;              p_32 ^= tmp;
+        tmp = *data++; block ^= tmp;             p_16 ^= tmp; p_32 ^= tmp;
+        tmp = *data++; block ^= tmp; p_8 ^= tmp; p_16 ^= tmp; p_32 ^= tmp;
+        
+        p_col ^= block;
+        if(nand_get_parity(block)) p_hi ^= i;
+    }
+    
+    // Get ecc from parity values
+    ecc = p_hi << 6;                            // p_64 - p_1024
+    ecc |= nand_get_parity(p_32) << 5;          // p_32
+    ecc |= nand_get_parity(p_16) << 4;          // p_16
+    ecc |= nand_get_parity(p_8) << 3;           // p_8
+    ecc |= nand_get_parity(p_col & 0xF0) << 2;  // p_4
+    ecc |= nand_get_parity(p_col & 0xCC) << 1;  // p_2
+    ecc |= nand_get_parity(p_col & 0xAA);       // p_1
+    
+    // If parity of whole array is even, first and second ecc parts are equal
+    // If it's odd, second part is equal to inverse of first part
+    if(nand_get_parity(p_col)) ecc |= (ecc ^ 0x7FF) << 11;
+    else ecc |= ecc << 11;
+    
+    return ecc;
+}
+
+static int nand_check_ecc(cyg_uint8* data, cyg_uint32 ecc)
+{
+    cyg_uint32 err;
+    int err_cnt = 0;
+    
+    // Calc ecc and get error info
+    ecc = (ecc & 0x3FFFFF) ^ nand_calc_ecc(data);
+    
+    // Count errors
+    for(err = ecc; err; err >>= 1) err_cnt += err & 1;
+    
+    // Check errors
+    if(err_cnt < 2)
+    {
+        // No error or 1 bit error in ecc area => nothing to repair
+        return 1;
+    }
+    else if(err_cnt == 11)
+    {
+        // This is 1 bit error in data area => repair this bit
+        data[(ecc & 0x7FF) >> 3] ^= (1 << (ecc & 7));
+        
+        return 1;
+    }
+    
+    return 0;
+}
+
+#endif
+
+//--------------------------------------------------------------------------
+// NAND command
+//--------------------------------------------------------------------------
+
+static void nand_command(int cmd, cyg_int32 column, cyg_int32 page_addr)
+{
+    if(cmd == NAND_CMD_SEQIN)
+    {
+        // Set data pointer to page beginning
+        CYGHWR_FLASH_NAND_PLF_CMD(NAND_CMD_READ0);
+    }
+    
+    // Write NAND command
+    CYGHWR_FLASH_NAND_PLF_CMD(cmd);
+    
+    // Write column number if needed
+    if(column >= 0)
+    {
+        CYGHWR_FLASH_NAND_PLF_ADDR(column);
+    }
+    
+    // Write page address if needed
+    if(page_addr >= 0)
+    {
+        CYGHWR_FLASH_NAND_PLF_ADDR(page_addr & 0xFF);
+        CYGHWR_FLASH_NAND_PLF_ADDR(page_addr >> 8);
+    }
+    
+    if(cmd == NAND_CMD_ERASE)
+    {
+        CYGHWR_FLASH_NAND_PLF_CMD(NAND_CMD_ERASE2);
+    }
+    
+    // Delay after command and address
+    CYGACC_CALL_IF_DELAY_US(nand_device.delay_cmd);
+}
+
+//--------------------------------------------------------------------------
+// NAND erase block
+//--------------------------------------------------------------------------
+
+static int nand_erase_block(cyg_int32 page_addr)
+{
+    int status, res = FLASH_ERR_OK;
+    
+    DEBUG_PRINT_HDW("Erase block %p - ", page_addr);
+    
+    CYGHWR_FLASH_NAND_PLF_CE(1);
+    CYGHWR_FLASH_NAND_PLF_WP(0);
+    
+    // Erase block
+    nand_command(NAND_CMD_ERASE, -1, page_addr);
+    CYGHWR_FLASH_NAND_PLF_WAIT();
+    
+    // Read operation status and check it
+    nand_command(NAND_CMD_STATUS, -1, -1);
+    status = nand_read_byte();
+    
+    CYGHWR_FLASH_NAND_PLF_WP(1);
+    CYGHWR_FLASH_NAND_PLF_CE(0);
+    
+    if(!(status & NAND_STATUS_READY)) res = FLASH_ERR_DRV_TIMEOUT;
+    else if(!(status & NAND_STATUS_NOWP)) res = FLASH_ERR_PROTECT;
+    else if(status & NAND_STATUS_FAIL) res = FLASH_ERR_ERASE;
+    
+    if(res == FLASH_ERR_OK) DEBUG_PRINT_HDW("Succeed\n");
+    else DEBUG_PRINT_HDW("Failed (status = 0x%X)\n", status);
+    
+    return res;
+}
+
+//--------------------------------------------------------------------------
+// NAND read page
+//--------------------------------------------------------------------------
+
+static int nand_read_page(cyg_int32 page_addr, cyg_uint8* data,
+        cyg_uint8* spare)
+{
+    cyg_nand_dev* dev = &nand_device;
+    
+    DEBUG_PRINT_HDW("Read page %p - ", page_addr);
+    
+    CYGHWR_FLASH_NAND_PLF_CE(1);
+    
+    // Write Read0 command and address
+    nand_command(NAND_CMD_READ0, 0x00, page_addr);
+    
+    // Wait device ready pin
+    CYGHWR_FLASH_NAND_PLF_WAIT();
+    
+    // Read data and spare fields
+    nand_read_buf(data, dev->page_size);
+    nand_read_buf(spare, dev->spare_size);
+    
+    CYGHWR_FLASH_NAND_PLF_CE(0);
+    
+#if defined(CYGSEM_DEVS_FLASH_NAND_ECC_SOFT)
+    
+    // Don't look at the result of nand_check_ecc(),
+    // we should read the page in any case
+    if(dev->page_size == 256)
+    {
+        nand_check_ecc(data, spare[0] | (spare[1] << 8) | (spare[2] << 16));
+    }
+    else if(dev->page_size == 512)
+    {
+        nand_check_ecc(data, spare[0] | (spare[1] << 8) | (spare[2] << 16));
+        nand_check_ecc(data + 256, spare[3] | (spare[6] << 8) | (spare[7] << 16));
+    }
+    else
+    {
+        DEBUG_PRINT_HDW("Unknown page size\n");
+        return FLASH_ERR_HWR;
+    }
+    
+#endif
+    
+    DEBUG_PRINT_HDW("Succeed\n");
+    
+    return FLASH_ERR_OK;
+}
+
+//--------------------------------------------------------------------------
+// NAND write page
+//--------------------------------------------------------------------------
+
+static int nand_write_page(cyg_int32 page_addr, cyg_uint8* data,
+        cyg_uint8* spare)
+{
+    cyg_nand_dev* dev = &nand_device;
+    int status, res = FLASH_ERR_OK;
+    
+#if defined(CYGSEM_DEVS_FLASH_NAND_ECC_SOFT)
+    cyg_uint32 ecc;
+#endif
+    
+    DEBUG_PRINT_HDW("Program page %p - ", page_addr);
+    
+    // Fill spare area
+    memset(spare, 0xFF, dev->spare_size);
+    
+#if defined(CYGSEM_DEVS_FLASH_NAND_ECC_SOFT)
+    
+    if(dev->page_size == 256)
+    {
+        ecc = nand_calc_ecc(data);
+        spare[0] = ecc & 0xFF;
+        spare[1] = (ecc >> 8) & 0xFF;
+        spare[2] = (ecc >> 16) & 0xFF;
+    }
+    else if(dev->page_size == 512)
+    {
+        ecc = nand_calc_ecc(data);
+        spare[0] = ecc & 0xFF;
+        spare[1] = (ecc >> 8) & 0xFF;
+        spare[2] = (ecc >> 16) & 0xFF;
+        
+        ecc = nand_calc_ecc(data + 256);
+        spare[3] = ecc & 0xFF;
+        spare[6] = (ecc >> 8) & 0xFF;
+        spare[7] = (ecc >> 16) & 0xFF;
+    }
+    else
+    {
+        DEBUG_PRINT_HDW("Unknown page size\n");
+        return FLASH_ERR_HWR;
+    }
+    
+#endif
+    
+    CYGHWR_FLASH_NAND_PLF_CE(1);
+    CYGHWR_FLASH_NAND_PLF_WP(0);
+    
+    // Write data and spare fields
+    nand_command(NAND_CMD_SEQIN, 0x00, page_addr);
+    nand_write_buf(data, dev->page_size);
+    nand_write_buf(spare, dev->spare_size);
+    
+    // Programm page
+    nand_command(NAND_CMD_PAGEPROG, -1, -1);
+    CYGHWR_FLASH_NAND_PLF_WAIT();
+    
+    // Read operation status and check it
+    nand_command(NAND_CMD_STATUS, -1, -1);
+    status = nand_read_byte();
+    
+    CYGHWR_FLASH_NAND_PLF_WP(1);
+    CYGHWR_FLASH_NAND_PLF_CE(0);
+    
+    if(!(status & NAND_STATUS_READY)) res = FLASH_ERR_DRV_TIMEOUT;
+    else if(!(status & NAND_STATUS_NOWP)) res = FLASH_ERR_PROTECT;
+    else if(status & NAND_STATUS_FAIL) res = FLASH_ERR_PROGRAM;
+    
+    if(res == FLASH_ERR_OK) DEBUG_PRINT_HDW("Succeed\n");
+    else DEBUG_PRINT_HDW("Failed (status = 0x%X)\n", status);
+    
+    return res;
+}
+
+//--------------------------------------------------------------------------
+// Check block
+//--------------------------------------------------------------------------
+
+static inline int nand_bbm_isbad(cyg_int32 block)
+{
+    return nand_device.buf_bbt[block >> 3] & (1 << (block & 0x07));
+}
+
+//--------------------------------------------------------------------------
+// Mark block as bad
+//--------------------------------------------------------------------------
+
+static inline void nand_bbm_markbad(cyg_int32 block)
+{
+    nand_device.buf_bbt[block >> 3] |= 1 << (block & 0x07);
+}
+
+//--------------------------------------------------------------------------
+// Check manufacturer bad block marker
+//--------------------------------------------------------------------------
+
+static int nand_bbm_checkmarker(cyg_int32 block)
+{
+    cyg_nand_dev* dev = &nand_device;
+    cyg_int32 page_addr;
+    int res = 0;
+    
+    dev->pageinbuf = -1;
+    page_addr = block << dev->block_shift;
+    
+    // Read first page spare area
+    CYGHWR_FLASH_NAND_PLF_CE(1);
+    
+    nand_command(NAND_CMD_READSPARE, 0x00, page_addr);
+    CYGHWR_FLASH_NAND_PLF_WAIT();
+    nand_read_buf(dev->buf_spare, dev->spare_size);
+    
+    CYGHWR_FLASH_NAND_PLF_CE(0);
+    
+    if(dev->buf_spare[0x05] != 0xFF) res = 1;
+    else
+    {
+        // Read second page spare area
+        CYGHWR_FLASH_NAND_PLF_CE(1);
+        
+        nand_command(NAND_CMD_READSPARE, 0x00, page_addr + 1);
+        CYGHWR_FLASH_NAND_PLF_WAIT();
+        nand_read_buf(dev->buf_spare, dev->spare_size);
+        
+        CYGHWR_FLASH_NAND_PLF_CE(0);
+        
+        if(dev->buf_spare[0x05] != 0xFF) res = 1;
+    }
+    
+    return res;
+}
+
+//--------------------------------------------------------------------------
+// Load bad block management info
+// TODO: Work with different endian format
+//--------------------------------------------------------------------------
+
+#if defined(CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR)
+
+static int nand_bbm_load(cyg_int32 block)
+{
+    cyg_nand_dev* dev = &nand_device;
+    cyg_int32 page_addr;
+    cyg_uint32 info[2];
+    cyg_uint32 i, len, size;
+    int res;
+    
+    DEBUG_PRINT_CMD("Load bbm info from %d block\n", block);
+    
+    dev->pageinbuf = -1;
+    page_addr = block << dev->block_shift;
+    
+    // Read first page in this block
+    res = nand_read_page(page_addr++, dev->buf_data, dev->buf_spare);
+    if(res != FLASH_ERR_OK)
+    {
+        DEBUG_PRINT_CMD("Load bbm: Page read error\n");
+        return res;
+    }
+    
+    memcpy(info, &dev->buf_data[sizeof(nand_bbm_id)], sizeof(info));
+    
+    // Check id string, device id and repair area size
+    if(strncmp((char*) dev->buf_data, nand_bbm_id, sizeof(nand_bbm_id)) != 0 || 
+            info[0] != dev->id || info[1] != NAND_REPAIR_SIZE)
+    {
+        DEBUG_PRINT_CMD("Load bbm: This is not bbm info block\n");
+        return FLASH_ERR_HWR;
+    }
+    
+    // We found management info => Read remap table (next pages)
+    i = 0; len = NAND_REPAIR_SIZE * sizeof(cyg_int32);
+    while(i < len)
+    {
+        size  = len - i;
+        if(size > dev->page_size) size = dev->page_size;
+        
+        res = nand_read_page(page_addr++, dev->buf_data, dev->buf_spare);
+        if(res != FLASH_ERR_OK)
+        {
+            DEBUG_PRINT_CMD("Load bbm: Page read error\n");
+            return res;
+        }
+        
+        memcpy(((cyg_uint8*) dev->bbm_remap) + i, dev->buf_data, size);
+        i += size;
+    }
+    
+    DEBUG_PRINT_CMD("Load bbm: Succeed\n");
+    return FLASH_ERR_OK;
+}
+
+#endif /*CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR*/
+
+//--------------------------------------------------------------------------
+// Save bad block management info
+// TODO: Work with different endian format
+//--------------------------------------------------------------------------
+
+#if defined(CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR)
+
+static int nand_bbm_save(cyg_int32 block)
+{
+    cyg_nand_dev* dev = &nand_device;
+    cyg_int32 page_addr;
+    cyg_uint32 info[2];
+    cyg_uint32 i, len, size;
+    int res;
+    
+    DEBUG_PRINT_CMD("Save bbm info to %d block\n", block);
+    
+    dev->pageinbuf = -1;
+    page_addr = block << dev->block_shift;
+    
+    // Erase block
+    res = nand_erase_block(page_addr);
+    if(res != FLASH_ERR_OK)
+    {
+        DEBUG_PRINT_CMD("Save bbm: Erase error\n");
+        return res;
+    }
+    
+    // Copy id string, device id and repair area size
+    info[0] = dev->id; info[1] = NAND_REPAIR_SIZE;
+    memcpy(&dev->buf_data[0], nand_bbm_id, sizeof(nand_bbm_id));
+    memcpy(&dev->buf_data[sizeof(nand_bbm_id)], info, sizeof(info));
+    
+    res = nand_write_page(page_addr++, dev->buf_data, dev->buf_spare);
+    if(res != FLASH_ERR_OK)
+    {
+        DEBUG_PRINT_CMD("Save bbm: Page program error\n");
+        return res;
+    }
+    
+    // Save remap table (next pages)
+    i = 0; len = NAND_REPAIR_SIZE * sizeof(cyg_int32);
+    while(i < len)
+    {
+        size  = len - i;
+        if(size > dev->page_size) size = dev->page_size;
+        
+        memcpy(dev->buf_data, ((cyg_uint8*) dev->bbm_remap) + i, size);
+        memset(&dev->buf_data[size], 0xFF, dev->page_size - size);
+        
+        res = nand_write_page(page_addr++, dev->buf_data, dev->buf_spare);
+        if(res != FLASH_ERR_OK)
+        {
+            DEBUG_PRINT_CMD("Save bbm: Page program error\n");
+            return res;
+        }
+        
+        i += size;
+    }
+    
+    DEBUG_PRINT_CMD("Save bbm: Succeed\n");
+    return FLASH_ERR_OK;
+}
+
+#endif /*CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR*/
+
+//--------------------------------------------------------------------------
+// Remap bad block
+//--------------------------------------------------------------------------
+
+#if defined(CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR)
+
+static cyg_int32 nand_bbm_remap(cyg_int32 block)
+{
+    cyg_nand_dev* dev = &nand_device;
+    cyg_int32 first, virtual;
+    int i;
+    
+    DEBUG_PRINT_CMD("Remap %d block\n", block);
+    
+    // Mark block as bad in bad block table
+    nand_bbm_markbad(block);
+    
+    // Number of first block in repair area
+    first = dev->blocks_count - NAND_REPAIR_SIZE;
+    
+    // Bad block in repair area?
+    if(block >= first)
+    {
+        // Get virtual block number and mark block as bad in remap table 
+        virtual = dev->bbm_remap[block - first];
+        dev->bbm_remap[block - first] = block;
+    }
+    else virtual = block;
+    
+    // Find free block in remap area
+    for(i = 0; i < NAND_REPAIR_SIZE; i++)
+        if(dev->bbm_remap[i] < 0) break;
+    
+    if(i >= NAND_REPAIR_SIZE)
+    {
+        DEBUG_PRINT_CMD("Remap: No free blocks in repair area\n");
+        return -1;
+    }
+    
+    // Remap bad block
+    dev->bbm_remap[i] = virtual;
+    
+    // Return repair block number
+    block = first + i;
+    
+    DEBUG_PRINT_CMD("Remap: Remapped to %d block\n", block);
+    return block;
+}
+
+#endif /*CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR*/
+
+//--------------------------------------------------------------------------
+// Init bad block management data
+//--------------------------------------------------------------------------
+
+static int nand_bbm_init(void)
+{
+    cyg_nand_dev* dev = &nand_device;
+    
+#if defined(CYGSEM_DEVS_FLASH_NAND_BBM_INIT)
+    
+    cyg_int32 block;
+    int bbcount = 0;
+    
+    DEBUG_PRINT_CMD("Scan manufacture marked bad blocks\n");
+    
+    // Mark all blocks as good
+    memset(dev->buf_bbt, 0x00, dev->blocks_count / 8);
+    
+    // Scan manufacture marked bad blocks
+    for(block = 0; block < dev->blocks_count; block++)
+        if(nand_bbm_checkmarker(block))
+        {
+            nand_bbm_markbad(block);
+            bbcount++;
+        }
+    
+    DEBUG_PRINT_CMD("Scan: found %d bad blocks\n", bbcount);
+    
+    return FLASH_ERR_OK;
+    
+#elif defined(CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR)
+    
+    cyg_int32 block, first;
+    int i, res;
+    
+    DEBUG_PRINT_CMD("Init bbm info\n");
+    
+    // Mark all blocks as good
+    memset(dev->buf_bbt, 0x00, dev->blocks_count / 8);
+    
+    // Find last not bad block in the flash
+    dev->bbm_info = dev->blocks_count - 1;
+    for(i = 0; i < NAND_REPAIR_SIZE; i++, dev->bbm_info--)
+        if(!nand_bbm_checkmarker(dev->bbm_info)) break;
+    
+    // If there are no good blocks => return false
+    if(i >= NAND_REPAIR_SIZE)
+    {
+        DEBUG_PRINT_CMD("Init bbm: No good blocks in repair area\n");
+        return FLASH_ERR_HWR;
+    }
+    
+    first = dev->blocks_count - NAND_REPAIR_SIZE;
+    
+    // Try to load bad block management info
+    if(nand_bbm_load(dev->bbm_info) == FLASH_ERR_OK)
+    {
+        // Restore bad block table from remap table:
+        // If block in remap area is free, it is less than 0
+        // else it contains bad block number which it remaps
+        // If this block is bad, it contains its own number
+        for(i = 0; i < NAND_REPAIR_SIZE; i++)
+            if(dev->bbm_remap[i] >= 0)
+            {
+                DEBUG_PRINT_CMD("Remap table: Block %d is remapped to %d\n",
+                        dev->bbm_remap[i], first + i);
+                nand_bbm_markbad(dev->bbm_remap[i]);
+            }
+        
+        DEBUG_PRINT_CMD("Init bbm: Succeed\n");
+        return FLASH_ERR_OK;
+    }
+    
+    // Load failed, try to create bad block management info
+    DEBUG_PRINT_CMD("Init bbm: Load failed. Try to create bbm info.\n");
+    
+    // Check blocks in repair area
+    block = first;
+    for(i = 0; i < NAND_REPAIR_SIZE; i++, block++)
+    {
+        if(!nand_bbm_checkmarker(block)) dev->bbm_remap[i] = -1;
+        else dev->bbm_remap[i] = block;
+    }
+    
+    // Mark block with management info as bad
+    dev->bbm_remap[dev->bbm_info - first] = dev->bbm_info;
+        
+    // Scan bad blocks and remap its
+    for(block = 0; block < first; block++)
+        if(nand_bbm_checkmarker(block))
+            if(nand_bbm_remap(block) < 0)
+            {
+                DEBUG_PRINT_CMD("Init bbm: Repair area is too small\n");
+                return FLASH_ERR_HWR;
+            }
+    
+    // Save bad block management info
+    res = nand_bbm_save(dev->bbm_info);
+    
+    if(res == FLASH_ERR_OK) DEBUG_PRINT_CMD("Init bbm: Succeed\n");
+    else DEBUG_PRINT_CMD("Init bbm: Cannot save bbm info\n");
+    
+    return res;
+    
+#else
+    #error Unknown bad block management type
+#endif
+}
+
+//--------------------------------------------------------------------------
+// Get real page number (or return -1 if there are no such page)
+//--------------------------------------------------------------------------
+
+static cyg_int32 nand_bbm_getpage(cyg_int32 page_addr)
+{
+    cyg_nand_dev* dev = &nand_device;
+    
+#if defined(CYGSEM_DEVS_FLASH_NAND_BBM_INIT)
+    
+    cyg_int32 block;
+    
+    // If there are no such block or it's bad => return -1
+    block = page_addr >> dev->block_shift;
+    if((block >= dev->blocks_count) || nand_bbm_isbad(block)) return -1;
+    
+    return page_addr;
+    
+#elif defined(CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR)
+    
+    int i;
+    cyg_int32 block, first;
+    
+    // First block in repair area
+    first = dev->blocks_count - NAND_REPAIR_SIZE;
+    
+    // If there are no such block => return -1
+    block = page_addr >> dev->block_shift;
+    if(block >= first) return -1;
+    
+    // If block is not bad return initial page address
+    if(!nand_bbm_isbad(block)) return page_addr;
+    
+    // Block is bad => look up to remap table
+    for(i = 0; i < NAND_REPAIR_SIZE; i++)
+        if(dev->bbm_remap[i] == block)
+            return ((first + i) << dev->block_shift) |
+                (page_addr & (dev->pages_count - 1));
+    
+    // This bad block is not remapped
+    return -1;
+    
+#else
+    #error Unknown bad block management type
+#endif
+}
+
+//--------------------------------------------------------------------------
+// Erase failed handler
+//--------------------------------------------------------------------------
+
+static cyg_int32 nand_bbm_erasefailed(cyg_int32 page_addr)
+{
+    cyg_nand_dev* dev = &nand_device;
+    
+#if defined(CYGSEM_DEVS_FLASH_NAND_BBM_INIT)
+    
+    DEBUG_PRINT_CMD("Erase fail handler\n");
+    
+    // Mark this block as bad
+    nand_bbm_markbad(page_addr >> dev->block_shift);
+    return -1;
+    
+#elif defined(CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR)
+    
+    cyg_int32 bad, replacer;
+    int res;
+    
+    DEBUG_PRINT_CMD("Erase fail handler\n");
+    
+    // Get bad block
+    replacer = bad = page_addr >> dev->block_shift;
+    
+    // Do while there are blocks in repair area
+    while((replacer = nand_bbm_remap(replacer)) >= 0)
+    {
+        // Try to erase gotten block
+        res = nand_erase_block(replacer << dev->block_shift);
+        if(res == FLASH_ERR_ERASE) continue;
+        else if(res != FLASH_ERR_OK) return -1;
+        
+        // Save changed bad block managenent info
+        nand_bbm_save(dev->bbm_info);
+        
+        // Return new page address
+        return (replacer << dev->block_shift) | 
+            (page_addr & (dev->pages_count - 1));
+    }
+    
+    // There are no blocks in repair area
+    // Don't save bbm info, because it could be caused from hardware error
+    return -1;
+    
+#else
+    #error Unknown bad block management type
+#endif
+}
+
+//--------------------------------------------------------------------------
+// Program failed handler
+//--------------------------------------------------------------------------
+
+static cyg_int32 nand_bbm_progfailed(cyg_int32 page_addr)
+{
+    cyg_nand_dev* dev = &nand_device;
+    
+#if defined(CYGSEM_DEVS_FLASH_NAND_BBM_INIT)
+    
+    DEBUG_PRINT_CMD("Program fail handler\n");
+    
+    // Mark this block as bad
+    nand_bbm_markbad(page_addr >> dev->block_shift);
+    return -1;
+    
+#elif defined(CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR)
+    
+    cyg_int32 bad, replacer;
+    cyg_int32 page_err, page_i;
+    cyg_uint32 i;
+    int res;
+    
+    DEBUG_PRINT_CMD("Program fail handler\n");
+    
+    // Get bad block
+    replacer = bad = page_addr >> dev->block_shift;
+    
+    // Do while there are blocks in repair area
+    while((replacer = nand_bbm_remap(replacer)) >= 0)
+    {
+        // Try to erase gotten block
+        res = nand_erase_block(replacer << dev->block_shift);
+        if(res == FLASH_ERR_ERASE) continue;
+        else if(res != FLASH_ERR_OK) return -1;
+        
+        // Reset page buffer
+        dev->pageinbuf = -1;
+        
+        // Try to copy all not 0xFF pages to gotten block
+        page_err = page_addr & (dev->pages_count - 1);
+        for(page_i = 0; page_i < dev->pages_count; page_i++)
+        {
+            // Don't copy error page
+            if(page_i == page_err) continue;
+            
+            // Read next page from bad block. If error => skip the page
+            res = nand_read_page((bad << dev->block_shift) | page_i,
+                    dev->buf_data, dev->buf_spare);
+            if(res != FLASH_ERR_OK) continue;
+            
+            // Check page content. If all bytes are 0xFF => skip the page
+            for(i = 0; i < dev->page_size; i++)
+                if(dev->buf_data[i] != 0xFF) break;
+            
+            if(i >= dev->page_size) continue;
+            
+            // Write page to replace block. If error => return error
+            res = nand_write_page((replacer << dev->block_shift) | page_i,
+                    dev->buf_data, dev->buf_spare);
+            if(res != FLASH_ERR_OK) return -1;
+        }
+        
+        // Save changed bad block managenent info
+        nand_bbm_save(dev->bbm_info);
+        
+        // Return new page address
+        return (replacer << dev->block_shift) | page_err;
+    }
+    
+    // There are no blocks in repair area
+    // Don't save bbm info, because it could be caused from hardware error
+    return -1;
+    
+#else
+    #error Unknown bad block management type
+#endif
+}
+
+//--------------------------------------------------------------------------
+// Flash Query
+//--------------------------------------------------------------------------
+
+void flash_query(void* data)
+{
+    cyg_uint32* ids = (cyg_uint32*) data;
+    
+    DEBUG_PRINT_CMD("Query NAND flash ids\n");
+    
+    CYGHWR_FLASH_NAND_PLF_CE(1);
+    
+    // TODO: Reset flash
+    
+    
+    // Get manuf and device ids
+    nand_command(NAND_CMD_READID, 0x00, -1);
+    ids[0] = nand_read_byte();
+    ids[1] = nand_read_byte();
+    
+    CYGHWR_FLASH_NAND_PLF_CE(0);
+    
+    DEBUG_PRINT_CMD("Query: Manuf ID = 0x%X, Device ID = 0x%X\n", ids[0], ids[1]);
+}
+
+//--------------------------------------------------------------------------
+// Initialize driver
+//--------------------------------------------------------------------------
+
+int flash_hwr_init(void)
+{
+    cyg_nand_dev* dev = &nand_device;
+    int i, buflen, total;
+    cyg_uint32 ids[2];
+    
+    DEBUG_PRINT_CMD("Initialize NAND flash\n");
+    
+    // Call platform nand init function
+    CYGHWR_FLASH_NAND_PLF_INIT();
+    
+    // Get flash ids
+    flash_query((void*) ids);
+    
+    // Look up supported device
+    for(i = 0; i < NAND_SUPPORTED_COUNT; i++)
+        if(nand_supported[i].id == ids[1]) break;
+    
+    // if we didn't find the device return error
+    if(i >= NAND_SUPPORTED_COUNT)
+    {
+        DEBUG_PRINT_ERR("NAND_ERR: driver doesn't support "
+                "0x%X device ID\n", ids[1]);
+        return FLASH_ERR_DRV_WRONG_PART;
+    }
+    
+    // Copy device info
+    dev->id = ids[1];
+    dev->page_size = nand_supported[i].page_size;
+    dev->spare_size = dev->page_size / 32;
+    dev->pages_count = nand_supported[i].pages_count;
+    dev->blocks_count = nand_supported[i].blocks_count;
+    
+    dev->page_shift = nand_ffs(dev->page_size - 1);
+    dev->block_shift = nand_ffs(dev->pages_count - 1);
+    
+    // Check data buffer length
+    buflen = dev->page_size + dev->spare_size + dev->blocks_count / 8;
+    if(buflen > sizeof(nand_buffer))
+    {
+        DEBUG_PRINT_ERR("NAND_ERR: driver doesn't have enough buffer. "
+                "This flash needs at least %d bytes buffer\n", buflen);
+        return FLASH_ERR_DRV_WRONG_PART;
+    }
+    
+    // Allocate buffers
+    dev->buf_data = &nand_buffer[0];
+    dev->buf_spare = &nand_buffer[dev->page_size];
+    dev->buf_bbt = &nand_buffer[dev->page_size + dev->spare_size];
+    
+    // No page in buffer
+    dev->pageinbuf = -1;
+    
+    // Fill in device details
+#if defined(CYGSEM_DEVS_FLASH_NAND_BBM_INIT)
+    flash_info.blocks = dev->blocks_count;
+#elif defined(CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR)
+    flash_info.blocks = dev->blocks_count - NAND_REPAIR_SIZE;
+#else
+    #error Unknown bad block management type
+#endif
+    
+    flash_info.block_size = dev->page_size * dev->pages_count;
+    total = flash_info.block_size * flash_info.blocks;
+    flash_info.start = dev->flash_base;
+    flash_info.end = (void *)(((unsigned int) dev->flash_base) + total);
+    
+    // Init bad block management
+    if(nand_bbm_init() != FLASH_ERR_OK)
+    {
+        DEBUG_PRINT_ERR("NAND_ERR: Bad block management "
+                "initialisation is failed\n");
+        return FLASH_ERR_HWR;
+    }
+    
+    DEBUG_PRINT_CMD("Init NAND: Succeed (found %dMB flash)\n",
+            flash_info.block_size * dev->blocks_count / 0x100000);
+    return FLASH_ERR_OK;
+}
+
+//--------------------------------------------------------------------------
+// Erase Block
+//--------------------------------------------------------------------------
+
+int flash_erase_block(void* block, unsigned int size)
+{
+    cyg_nand_dev* dev = &nand_device;
+    cyg_int32 flash_addr, page_addr;
+    int res;
+    
+    DEBUG_PRINT_CMD("Erase %d bytes from %p\n", size, block);
+    
+    // Get flash addresses
+    flash_addr = (unsigned int) block - (unsigned int) dev->flash_base;
+    page_addr = nand_bbm_getpage(flash_addr >> dev->page_shift);
+    if(page_addr < 0) return FLASH_ERR_INVALID;
+    
+    res = nand_erase_block(page_addr);
+    if(res != FLASH_ERR_ERASE) return res;
+    
+    // Handle bad block error
+    if(nand_bbm_erasefailed(page_addr) < 0) return res;
+    
+    return FLASH_ERR_OK;
+}
+
+//--------------------------------------------------------------------------
+// Program Buffer
+//--------------------------------------------------------------------------
+
+int flash_program_buf(void* addr, void* data, int len)
+{
+    cyg_nand_dev* dev = &nand_device;
+    cyg_int32 flash_addr, column, page_addr;
+    int count, res;
+    
+    DEBUG_PRINT_CMD("Program %d bytes to %p\n", len, addr);
+    
+    // Get flash addresses
+    flash_addr = (unsigned int) addr - (unsigned int) dev->flash_base;
+    column = flash_addr & (dev->page_size - 1);
+    page_addr = nand_bbm_getpage(flash_addr >> dev->page_shift);
+    if(page_addr < 0) return FLASH_ERR_INVALID;
+    
+    while(len > 0)
+    {
+        // Should we program the whole page?
+        if(column == 0 && len >= dev->page_size)
+        {
+            // Reset buffer if we program the same page
+            if(page_addr == dev->pageinbuf) dev->pageinbuf = -1;
+            
+            // Write from user buffer, skip unnecessary copying
+            // It is useful then we are writing a large block of data
+            count = dev->page_size;
+            res = nand_write_page(page_addr, data, dev->buf_spare);
+        }
+        else
+        {
+            // Reset buffer
+            dev->pageinbuf = -1;
+            
+            count = dev->page_size - column;
+            if(count > len) count = len;
+            
+            // Copy data to the device buffer
+            memset(dev->buf_data, 0xFF, dev->page_size);
+            memcpy(&dev->buf_data[column], data, count);
+            
+            // Write page
+            res = nand_write_page(page_addr, dev->buf_data, dev->buf_spare);
+        }
+        
+        // Check program result
+        if(res == FLASH_ERR_PROGRAM)
+        {
+            // Handle bad block error
+            page_addr = nand_bbm_progfailed(page_addr);
+            if(page_addr < 0) return FLASH_ERR_PROGRAM;
+            
+            // Try program this data to new page
+            // Other pages in the block has been copied by nand_bbm_progfailed()
+            continue;
+        }
+        else if(res != FLASH_ERR_OK) return res;
+        
+        // Next page
+        len -= count; page_addr++; column = 0;
+        data = (void*) ((cyg_uint8*) data + count);
+    }
+    
+    return FLASH_ERR_OK;
+}
+
+//--------------------------------------------------------------------------
+// Read data into buffer
+//--------------------------------------------------------------------------
+
+int flash_read_buf(void* addr, void* data, int len)
+{
+    cyg_nand_dev* dev = &nand_device;
+    cyg_int32 flash_addr, column, page_addr;
+    int count, res;
+    
+    DEBUG_PRINT_CMD("Read %d bytes from %p\n", len, addr);
+    
+    // Get flash addresses
+    flash_addr = (unsigned int) addr - (unsigned int) dev->flash_base;
+    column = flash_addr & (dev->page_size - 1);
+    page_addr = nand_bbm_getpage(flash_addr >> dev->page_shift);
+    if(page_addr < 0) return FLASH_ERR_INVALID;
+    
+    while(len > 0)
+    {
+        if(page_addr != dev->pageinbuf && column == 0 && len >= dev->page_size)
+        {
+            // We should read the whole page not from buffer
+            // Read to user buffer, skip unnecessary copying
+            // It is useful then we are reading a large block of data
+            res = nand_read_page(page_addr, data, dev->buf_spare);
+            if(res != FLASH_ERR_OK) return res;
+            
+            count = dev->page_size;
+        }
+        else
+        {
+            if(page_addr != dev->pageinbuf)
+            {
+                // Read page to the device buffer
+                res = nand_read_page(page_addr, dev->buf_data, dev->buf_spare);
+                if(res != FLASH_ERR_OK) return res;
+                
+                dev->pageinbuf = page_addr;
+            }
+            
+            count = dev->page_size - column;
+            if(count > len) count = len;
+            
+            // Copy data from device buffer to user buffer
+            memcpy(data, &dev->buf_data[column], count);
+            
+            // Next read operation start in beginning of page
+            column = 0;
+        }
+        
+        len -= count; page_addr++;
+        data = (void*) ((cyg_uint8*) data + count);
+    }
+    
+    return FLASH_ERR_OK;
+}
+
+//--------------------------------------------------------------------------
+// Format flash
+//--------------------------------------------------------------------------
+
+int flash_format(int all)
+{
+    cyg_nand_dev* dev = &nand_device;
+    cyg_int32 i;
+    
+    if(all)
+    {
+        DEBUG_PRINT_CMD("Format NAND Flash. Erase all blocks.\n");
+        
+        // Erase all blocks except manufacture marked bad blocks
+        for(i = 0; i < dev->blocks_count; i++)
+            if(!nand_bbm_checkmarker(i))
+                nand_erase_block(i << dev->block_shift);
+    }
+#if defined(CYGSEM_DEVS_FLASH_NAND_BBM_REPAIR)
+    else
+    {
+        DEBUG_PRINT_CMD("Format NAND Flash. Erase only bbm info block.\n");
+        
+        // Erase only bbm info block
+        nand_erase_block(dev->bbm_info << dev->block_shift);
+    }
+#endif
+    
+    // Init bbm info
+    return nand_bbm_init();
+}
+
+//--------------------------------------------------------------------------
+// Map a hardware status to a package error
+//--------------------------------------------------------------------------
+
+int flash_hwr_map_error(int e)
+{
+    return e;
+}
+
+//--------------------------------------------------------------------------
+// See if a range of FLASH addresses overlaps currently running code
+//--------------------------------------------------------------------------
+
+bool flash_code_overlaps(void *start, void *end)
+{
+    // Currently running code cannot be in NAND FLASH
+    return 0;
+}
+
+//--------------------------------------------------------------------------
+// EOF nand_flash.c
diff -bur -P /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/src/nand_flash_parts.inl ./devs/flash/nand/current/src/nand_flash_parts.inl
--- /opt/ecos-repo/cvs/ecos/packages/devs/flash/nand/current/src/nand_flash_parts.inl	1970-01-01 06:00:00.000000000 +0600
+++ ./devs/flash/nand/current/src/nand_flash_parts.inl	2007-12-05 16:51:22.000000000 +0600
@@ -0,0 +1,84 @@
+#ifndef _CYGONCE_FLASH_NAND_PARTS_INL_
+#define _CYGONCE_FLASH_NAND_PARTS_INL_
+//==========================================================================
+//
+//      nand_flash_parts.inl
+//
+//      FLASH memory - NAND flash parts descriptions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Alexey Shusharin <mrfinch@mail.ru>
+// Contributors: 
+// Date:         2007-11-16
+// Purpose:      
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+    
+static const cyg_nand_partinfo nand_supported[] = 
+{
+    //  Device ID   Page size   Pages count     Blocks count    Options
+    {   0x6E,       256,        16,             256,            0           }, //1MB
+    {   0x64,       256,        16,             512,            0           }, //2MB
+    {   0x6B,       512,        16,             512,            0           }, //4MB
+    {   0xE8,       256,        16,             256,            0           }, //1MB
+    {   0xEC,       256,        16,             256,            0           }, //1MB
+    {   0xEA,       256,        16,             512,            0           }, //2MB
+    {   0xD5,       512,        16,             512,            0           }, //4MB
+    {   0xE3,       512,        16,             512,            0           }, //4MB
+    {   0xE5,       512,        16,             512,            0           }, //4MB
+    {   0xD6,       512,        16,            1024,            0           }, //8MB
+    {   0x39,       512,        16,            1024,            0           }, //8MB
+    {   0xE6,       512,        16,            1024,            0           }, //8MB
+    {   0x33,       512,        32,            1024,            0           }, //16MB
+    {   0x73,       512,        32,            1024,            0           }, //16MB
+    {   0x35,       512,        32,            2048,            0           }, //32MB
+    {   0x75,       512,        32,            2048,            0           }, //32MB
+    {   0x36,       512,        32,            4096,            0           }, //64MB
+    {   0x76,       512,        32,            4096,            0           }, //64MB
+    {   0x78,       512,        32,            8192,            0           }, //128MB
+    {   0x39,       512,        32,            8192,            0           }, //128MB
+    {   0x79,       512,        32,            8192,            0           }, //128MB
+    {   0x71,       512,        32,           16384,            0           }, //256MB
+};
+
+#define NAND_SUPPORTED_COUNT    (sizeof(nand_supported) / sizeof(cyg_nand_partinfo))
+
+#endif // _CYGONCE_FLASH_NAND_PARTS_INL_
+//--------------------------------------------------------------------------
+// EOF nand_flash_parts.inl
diff -bur -P /opt/ecos-repo/cvs/ecos/packages/ecos.db ./ecos.db
--- /opt/ecos-repo/cvs/ecos/packages/ecos.db	2007-12-10 18:07:53.000000000 +0600
+++ ./ecos.db	2007-12-10 18:10:10.000000000 +0600
@@ -6372,4 +6372,12 @@
     description "Another Tiny HTTP server."
 }
 
+package CYGPKG_DEVS_FLASH_NAND {
+        alias           { "NAND FLASH memory support" nand_flash }
+        directory       devs/flash/nand
+        script          nand_flash.cdl
+        hardware
+        description "
+            This package provides a NAND FLASH memory device support."
+}
 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: NAND Flash device driver
  2007-12-10 13:01 NAND Flash device driver Alexey Shusharin
@ 2007-12-18  4:02 ` Alexey Shusharin
  2007-12-18  9:13   ` Andrew Lunn
  0 siblings, 1 reply; 10+ messages in thread
From: Alexey Shusharin @ 2007-12-18  4:02 UTC (permalink / raw)
  To: ecos-patches


В Пнд, 10/12/2007 в 19:01 +0600, Alexey Shusharin пишет:
> Hi,
> 
> This patch adds a NAND Flash device driver to flash V1 branch.
> 
> Currently it supports 8-bit NAND flash with 256/512 page size and has
> implemented software ECC and simple bad block management algorithms.
> 
> I've tested it with SAMSUNG K9F5608U0D.
> 
> Best regards
> Alexey Shusharin
> 

Hi guys!

What's wrong with this patch? Why you didn't answer?

Alexey


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: NAND Flash device driver
  2007-12-18  4:02 ` Alexey Shusharin
@ 2007-12-18  9:13   ` Andrew Lunn
  2007-12-18 10:37     ` Alexey Shusharin
  0 siblings, 1 reply; 10+ messages in thread
From: Andrew Lunn @ 2007-12-18  9:13 UTC (permalink / raw)
  To: Alexey Shusharin; +Cc: ecos-patches

On Tue, Dec 18, 2007 at 10:03:11AM +0600, Alexey Shusharin wrote:
> 
> ?? ??????, 10/12/2007 ?? 19:01 +0600, Alexey Shusharin ??????????:
> > Hi,
> > 
> > This patch adds a NAND Flash device driver to flash V1 branch.
> > 
> > Currently it supports 8-bit NAND flash with 256/512 page size and has
> > implemented software ECC and simple bad block management algorithms.
> > 
> > I've tested it with SAMSUNG K9F5608U0D.
> > 
> > Best regards
> > Alexey Shusharin
> > 
> 
> Hi guys!
> 
> What's wrong with this patch? Why you didn't answer?

I've never worked with a NAND device, so i did not feel too happy to
look at this patch. I hope one of the other maintainers has the
necessary background.

Having said that, i took a quick look at the code. I have some general
questions about NAND devices and drivers.

You have the ECC and bad block management code integrated with the
package. Is this specific to the Samsung device? I'm wondering if this
should be separated out, either into a new package, or made part of
io/flash with some CDL to control it. It then makes it possible for
other manufactures devices to use this code.

You say this is not compatible with Linux. How much effort is required
to make it compatible? A lot of people use eCos for RedBoot, booting
Linux. In this situation it is useful to be compatible with Linux.

       Andrew

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: NAND Flash device driver
  2007-12-18  9:13   ` Andrew Lunn
@ 2007-12-18 10:37     ` Alexey Shusharin
  2007-12-18 14:30       ` Gary Thomas
  0 siblings, 1 reply; 10+ messages in thread
From: Alexey Shusharin @ 2007-12-18 10:37 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-patches


В Втр, 18/12/2007 в 10:13 +0100, Andrew Lunn пишет:
> On Tue, Dec 18, 2007 at 10:03:11AM +0600, Alexey Shusharin wrote:
> > 
> > ?? ??????, 10/12/2007 ?? 19:01 +0600, Alexey Shusharin ??????????:
> > > Hi,
> > > 
> > > This patch adds a NAND Flash device driver to flash V1 branch.
> > > 
> > > Currently it supports 8-bit NAND flash with 256/512 page size and has
> > > implemented software ECC and simple bad block management algorithms.
> > > 
> > > I've tested it with SAMSUNG K9F5608U0D.
> > > 
> > > Best regards
> > > Alexey Shusharin
> > > 
> > 
> > Hi guys!
> > 
> > What's wrong with this patch? Why you didn't answer?
> 
> I've never worked with a NAND device, so i did not feel too happy to
> look at this patch. I hope one of the other maintainers has the
> necessary background.
> 
Hi,
Thanks for answer.

> Having said that, i took a quick look at the code. I have some general
> questions about NAND devices and drivers.
> 
> You have the ECC and bad block management code integrated with the
> package. Is this specific to the Samsung device? I'm wondering if this
> should be separated out, either into a new package, or made part of
> io/flash with some CDL to control it. It then makes it possible for
> other manufactures devices to use this code.

I didn't check all NAND devices, of course. But devices which i know
have identical memory arrangements and general access methods. They
differs only access times which is adjusted by platform code. Moreover,
Linux NAND driver doesn't distinguish between different manufacturers.
So i think this driver should work with different manufacturers devices.

If this statement is true the ECC and bad block management algorithms
depend of NAND page size only. This driver support only small page (256
or 512 bytes), but can be modified to support large page in the future
(device with large page has other command set).

Other issue is 16-bit bus width support. It's not difficult to add this
feature (add 3 small functions), but i cannot test it because have 8-bit
flash only.

> You say this is not compatible with Linux. How much effort is required
> to make it compatible? A lot of people use eCos for RedBoot, booting
> Linux. In this situation it is useful to be compatible with Linux.

Unfortunately Linux NAND driver has complex bad block management
algorithm and the best way to make driver compatible with Linux - get
code from it (this is that u-boot does). Therefore if i use other bbm
algorithm, it doesn't matter to use the same ECC algorithm, more so i
didn't find its description.

You can find more information about Linux NAND driver there:
http://www.linux-mtd.infradead.org/doc/nand.html
http://www.linux-mtd.infradead.org/tech/mtdnand/index.html

There are other reasons in using especial bbm algorithm.
eCos flash API doesn't have methods to works with NAND speciality (write
to spare area, check bad blocks and etc.) and RedBoot doesn't support
this features too. This driver hides NAND flash particularity and makes
it transparent for flash API and RedBoot FIS.

Maybe somebody has other opinion. You are welcome! ;-)

Best regards
Alexey Shusharin


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: NAND Flash device driver
  2007-12-18 10:37     ` Alexey Shusharin
@ 2007-12-18 14:30       ` Gary Thomas
  2007-12-18 15:17         ` Alexey Shusharin
  0 siblings, 1 reply; 10+ messages in thread
From: Gary Thomas @ 2007-12-18 14:30 UTC (permalink / raw)
  To: Alexey Shusharin; +Cc: ecos-patches

Alexey Shusharin wrote:
> В Втр, 18/12/2007 в 10:13 +0100, Andrew Lunn пишет:
>> On Tue, Dec 18, 2007 at 10:03:11AM +0600, Alexey Shusharin wrote:
>>> ?? ??????, 10/12/2007 ?? 19:01 +0600, Alexey Shusharin ??????????:
>>>> Hi,
>>>>
>>>> This patch adds a NAND Flash device driver to flash V1 branch.
>>>>
>>>> Currently it supports 8-bit NAND flash with 256/512 page size and has
>>>> implemented software ECC and simple bad block management algorithms.
>>>>
>>>> I've tested it with SAMSUNG K9F5608U0D.
>>>>
>>>> Best regards
>>>> Alexey Shusharin
>>>>
>>> Hi guys!
>>>
>>> What's wrong with this patch? Why you didn't answer?
>> I've never worked with a NAND device, so i did not feel too happy to
>> look at this patch. I hope one of the other maintainers has the
>> necessary background.
>>
> Hi,
> Thanks for answer.
> 
>> Having said that, i took a quick look at the code. I have some general
>> questions about NAND devices and drivers.
>>
>> You have the ECC and bad block management code integrated with the
>> package. Is this specific to the Samsung device? I'm wondering if this
>> should be separated out, either into a new package, or made part of
>> io/flash with some CDL to control it. It then makes it possible for
>> other manufactures devices to use this code.
> 
> I didn't check all NAND devices, of course. But devices which i know
> have identical memory arrangements and general access methods. They
> differs only access times which is adjusted by platform code. Moreover,
> Linux NAND driver doesn't distinguish between different manufacturers.
> So i think this driver should work with different manufacturers devices.
> 
> If this statement is true the ECC and bad block management algorithms
> depend of NAND page size only. This driver support only small page (256
> or 512 bytes), but can be modified to support large page in the future
> (device with large page has other command set).
> 
> Other issue is 16-bit bus width support. It's not difficult to add this
> feature (add 3 small functions), but i cannot test it because have 8-bit
> flash only.
> 
>> You say this is not compatible with Linux. How much effort is required
>> to make it compatible? A lot of people use eCos for RedBoot, booting
>> Linux. In this situation it is useful to be compatible with Linux.
> 
> Unfortunately Linux NAND driver has complex bad block management
> algorithm and the best way to make driver compatible with Linux - get
> code from it (this is that u-boot does). Therefore if i use other bbm
> algorithm, it doesn't matter to use the same ECC algorithm, more so i
> didn't find its description.
> 
> You can find more information about Linux NAND driver there:
> http://www.linux-mtd.infradead.org/doc/nand.html
> http://www.linux-mtd.infradead.org/tech/mtdnand/index.html
> 
> There are other reasons in using especial bbm algorithm.
> eCos flash API doesn't have methods to works with NAND speciality (write
> to spare area, check bad blocks and etc.) and RedBoot doesn't support
> this features too. This driver hides NAND flash particularity and makes
> it transparent for flash API and RedBoot FIS.
> 
> Maybe somebody has other opinion. You are welcome! ;-)

I've not had time to review this, but how different is it from
the existing Toshiba NAND device driver?


-- 
------------------------------------------------------------
Gary Thomas                 |  Consulting for the
MLB Associates              |    Embedded world
------------------------------------------------------------

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: NAND Flash device driver
  2007-12-18 14:30       ` Gary Thomas
@ 2007-12-18 15:17         ` Alexey Shusharin
  2007-12-20 12:11           ` Gary Thomas
  0 siblings, 1 reply; 10+ messages in thread
From: Alexey Shusharin @ 2007-12-18 15:17 UTC (permalink / raw)
  To: Gary Thomas; +Cc: ecos-patches

В Втр, 18/12/2007 в 07:30 -0700, Gary Thomas пишет:
> Alexey Shusharin wrote:
> > В Втр, 18/12/2007 в 10:13 +0100, Andrew Lunn пишет:
> >> On Tue, Dec 18, 2007 at 10:03:11AM +0600, Alexey Shusharin wrote:
> >>> ?? ??????, 10/12/2007 ?? 19:01 +0600, Alexey Shusharin ??????????:
> >>>> Hi,
> >>>>
> >>>> This patch adds a NAND Flash device driver to flash V1 branch.
> >>>>
> >>>> Currently it supports 8-bit NAND flash with 256/512 page size and has
> >>>> implemented software ECC and simple bad block management algorithms.
> >>>>
> >>>> I've tested it with SAMSUNG K9F5608U0D.
> >>>>
> >>>> Best regards
> >>>> Alexey Shusharin
> >>>>
> >>> Hi guys!
> >>>
> >>> What's wrong with this patch? Why you didn't answer?
> >> I've never worked with a NAND device, so i did not feel too happy to
> >> look at this patch. I hope one of the other maintainers has the
> >> necessary background.
> >>
> > Hi,
> > Thanks for answer.
> > 
> >> Having said that, i took a quick look at the code. I have some general
> >> questions about NAND devices and drivers.
> >>
> >> You have the ECC and bad block management code integrated with the
> >> package. Is this specific to the Samsung device? I'm wondering if this
> >> should be separated out, either into a new package, or made part of
> >> io/flash with some CDL to control it. It then makes it possible for
> >> other manufactures devices to use this code.
> > 
> > I didn't check all NAND devices, of course. But devices which i know
> > have identical memory arrangements and general access methods. They
> > differs only access times which is adjusted by platform code. Moreover,
> > Linux NAND driver doesn't distinguish between different manufacturers.
> > So i think this driver should work with different manufacturers devices.
> > 
> > If this statement is true the ECC and bad block management algorithms
> > depend of NAND page size only. This driver support only small page (256
> > or 512 bytes), but can be modified to support large page in the future
> > (device with large page has other command set).
> > 
> > Other issue is 16-bit bus width support. It's not difficult to add this
> > feature (add 3 small functions), but i cannot test it because have 8-bit
> > flash only.
> > 
> >> You say this is not compatible with Linux. How much effort is required
> >> to make it compatible? A lot of people use eCos for RedBoot, booting
> >> Linux. In this situation it is useful to be compatible with Linux.
> > 
> > Unfortunately Linux NAND driver has complex bad block management
> > algorithm and the best way to make driver compatible with Linux - get
> > code from it (this is that u-boot does). Therefore if i use other bbm
> > algorithm, it doesn't matter to use the same ECC algorithm, more so i
> > didn't find its description.
> > 
> > You can find more information about Linux NAND driver there:
> > http://www.linux-mtd.infradead.org/doc/nand.html
> > http://www.linux-mtd.infradead.org/tech/mtdnand/index.html
> > 
> > There are other reasons in using especial bbm algorithm.
> > eCos flash API doesn't have methods to works with NAND speciality (write
> > to spare area, check bad blocks and etc.) and RedBoot doesn't support
> > this features too. This driver hides NAND flash particularity and makes
> > it transparent for flash API and RedBoot FIS.
> > 
> > Maybe somebody has other opinion. You are welcome! ;-)
> 
> I've not had time to review this, but how different is it from
> the existing Toshiba NAND device driver?

In general:

 - It supports not only Toshiba chips.

 - It has own ECC code (not from Linux and so not GPL-infected).

 - It has page buffer in RAM so application can read any part of page
and doesn't worry about ECC (driver reads whole page and corrects data).
Buffer also allows to read data from one page several times without
access to chip.

 - It implements bad block management algorithm which reserves repair
area at the end of the flash and replace bad blocks in main area with
blocks from it. New bad blocks will be also replaced. Management
information resides in last not bad block.

Best regards
Alexey


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: NAND Flash device driver
  2007-12-18 15:17         ` Alexey Shusharin
@ 2007-12-20 12:11           ` Gary Thomas
  2007-12-20 12:35             ` Jonathan Larmour
  2007-12-20 13:42             ` Alexey Shusharin
  0 siblings, 2 replies; 10+ messages in thread
From: Gary Thomas @ 2007-12-20 12:11 UTC (permalink / raw)
  To: Alexey Shusharin; +Cc: ecos-patches

Alexey Shusharin wrote:
> В Втр, 18/12/2007 в 07:30 -0700, Gary Thomas пишет:
>> Alexey Shusharin wrote:
>>> В Втр, 18/12/2007 в 10:13 +0100, Andrew Lunn пишет:
>>>> On Tue, Dec 18, 2007 at 10:03:11AM +0600, Alexey Shusharin wrote:
>>>>> ?? ??????, 10/12/2007 ?? 19:01 +0600, Alexey Shusharin ??????????:
>>>>>> Hi,
>>>>>>
>>>>>> This patch adds a NAND Flash device driver to flash V1 branch.
>>>>>>
>>>>>> Currently it supports 8-bit NAND flash with 256/512 page size and has
>>>>>> implemented software ECC and simple bad block management algorithms.
>>>>>>
>>>>>> I've tested it with SAMSUNG K9F5608U0D.
>>>>>>
>>>>>> Best regards
>>>>>> Alexey Shusharin
>>>>>>
>>>>> Hi guys!
>>>>>
>>>>> What's wrong with this patch? Why you didn't answer?
>>>> I've never worked with a NAND device, so i did not feel too happy to
>>>> look at this patch. I hope one of the other maintainers has the
>>>> necessary background.
>>>>
>>> Hi,
>>> Thanks for answer.
>>>
>>>> Having said that, i took a quick look at the code. I have some general
>>>> questions about NAND devices and drivers.
>>>>
>>>> You have the ECC and bad block management code integrated with the
>>>> package. Is this specific to the Samsung device? I'm wondering if this
>>>> should be separated out, either into a new package, or made part of
>>>> io/flash with some CDL to control it. It then makes it possible for
>>>> other manufactures devices to use this code.
>>> I didn't check all NAND devices, of course. But devices which i know
>>> have identical memory arrangements and general access methods. They
>>> differs only access times which is adjusted by platform code. Moreover,
>>> Linux NAND driver doesn't distinguish between different manufacturers.
>>> So i think this driver should work with different manufacturers devices.
>>>
>>> If this statement is true the ECC and bad block management algorithms
>>> depend of NAND page size only. This driver support only small page (256
>>> or 512 bytes), but can be modified to support large page in the future
>>> (device with large page has other command set).
>>>
>>> Other issue is 16-bit bus width support. It's not difficult to add this
>>> feature (add 3 small functions), but i cannot test it because have 8-bit
>>> flash only.
>>>
>>>> You say this is not compatible with Linux. How much effort is required
>>>> to make it compatible? A lot of people use eCos for RedBoot, booting
>>>> Linux. In this situation it is useful to be compatible with Linux.
>>> Unfortunately Linux NAND driver has complex bad block management
>>> algorithm and the best way to make driver compatible with Linux - get
>>> code from it (this is that u-boot does). Therefore if i use other bbm
>>> algorithm, it doesn't matter to use the same ECC algorithm, more so i
>>> didn't find its description.
>>>
>>> You can find more information about Linux NAND driver there:
>>> http://www.linux-mtd.infradead.org/doc/nand.html
>>> http://www.linux-mtd.infradead.org/tech/mtdnand/index.html
>>>
>>> There are other reasons in using especial bbm algorithm.
>>> eCos flash API doesn't have methods to works with NAND speciality (write
>>> to spare area, check bad blocks and etc.) and RedBoot doesn't support
>>> this features too. This driver hides NAND flash particularity and makes
>>> it transparent for flash API and RedBoot FIS.
>>>
>>> Maybe somebody has other opinion. You are welcome! ;-)
>> I've not had time to review this, but how different is it from
>> the existing Toshiba NAND device driver?
> 
> In general:
> 
>  - It supports not only Toshiba chips.

Good.  Does it support the newer chips which have 4KB pages?

>  - It has own ECC code (not from Linux and so not GPL-infected).

As Andrew has said, to really be useful, the ECC management must be
compatible (if not borrowed from) Linux.

>  - It has page buffer in RAM so application can read any part of page
> and doesn't worry about ECC (driver reads whole page and corrects data).
> Buffer also allows to read data from one page several times without
> access to chip.

We already have a FLASH driver function for this (flash_read_buffer())
Why have two implementations?

>  - It implements bad block management algorithm which reserves repair
> area at the end of the flash and replace bad blocks in main area with
> blocks from it. New bad blocks will be also replaced. Management
> information resides in last not bad block.

Again, is this compatible with how Linux does it?

Virtually all "complex" platforms may end up running Linux at
one time or another, so we should strive to be as supportive
(compatible) as possible.  If your driver can be seen as an
upgrade to the existing driver(s), then this would be best
as having multiple solutions only causes grief...


-- 
------------------------------------------------------------
Gary Thomas                 |  Consulting for the
MLB Associates              |    Embedded world
------------------------------------------------------------

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: NAND Flash device driver
  2007-12-20 12:11           ` Gary Thomas
@ 2007-12-20 12:35             ` Jonathan Larmour
  2007-12-20 13:42             ` Alexey Shusharin
  1 sibling, 0 replies; 10+ messages in thread
From: Jonathan Larmour @ 2007-12-20 12:35 UTC (permalink / raw)
  To: Gary Thomas; +Cc: Alexey Shusharin, ecos-patches

Gary Thomas wrote:
> 
>>  - It has own ECC code (not from Linux and so not GPL-infected).
> 
> As Andrew has said, to really be useful, the ECC management must be
> compatible (if not borrowed from) Linux.

It cannot be borrowed from Linux as this would be fully GPLed. It would
have to be reimplemented (including definitions).

JFFS2 has the dual licence thing, but the rest of linux-mtd does not.

Jifl
-- 
eCosCentric Limited      http://www.eCosCentric.com/     The eCos experts
Barnwell House, Barnwell Drive, Cambridge, UK.       Tel: +44 1223 245571
Registered in England and Wales: Reg No 4422071.
------["Si fractum non sit, noli id reficere"]------       Opinions==mine

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: NAND Flash device driver
  2007-12-20 12:11           ` Gary Thomas
  2007-12-20 12:35             ` Jonathan Larmour
@ 2007-12-20 13:42             ` Alexey Shusharin
  2007-12-21  8:19               ` Alexey Shusharin
  1 sibling, 1 reply; 10+ messages in thread
From: Alexey Shusharin @ 2007-12-20 13:42 UTC (permalink / raw)
  To: Gary Thomas; +Cc: ecos-patches


В Чтв, 20/12/2007 в 05:10 -0700, Gary Thomas пишет:
> Alexey Shusharin wrote:
> > В Втр, 18/12/2007 в 07:30 -0700, Gary Thomas пишет:
> >> Alexey Shusharin wrote:
> >>> В Втр, 18/12/2007 в 10:13 +0100, Andrew Lunn пишет:
> >>>> On Tue, Dec 18, 2007 at 10:03:11AM +0600, Alexey Shusharin wrote:
> >>>>> ?? ??????, 10/12/2007 ?? 19:01 +0600, Alexey Shusharin ??????????:
> >>>>>> Hi,
> >>>>>>
> >>>>>> This patch adds a NAND Flash device driver to flash V1 branch.
> >>>>>>
> >>>>>> Currently it supports 8-bit NAND flash with 256/512 page size and has
> >>>>>> implemented software ECC and simple bad block management algorithms.
> >>>>>>
> >>>>>> I've tested it with SAMSUNG K9F5608U0D.
> >>>>>>
> >>>>>> Best regards
> >>>>>> Alexey Shusharin
> >>>>>>
> >>>>> Hi guys!
> >>>>>
> >>>>> What's wrong with this patch? Why you didn't answer?
> >>>> I've never worked with a NAND device, so i did not feel too happy to
> >>>> look at this patch. I hope one of the other maintainers has the
> >>>> necessary background.
> >>>>
> >>> Hi,
> >>> Thanks for answer.
> >>>
> >>>> Having said that, i took a quick look at the code. I have some general
> >>>> questions about NAND devices and drivers.
> >>>>
> >>>> You have the ECC and bad block management code integrated with the
> >>>> package. Is this specific to the Samsung device? I'm wondering if this
> >>>> should be separated out, either into a new package, or made part of
> >>>> io/flash with some CDL to control it. It then makes it possible for
> >>>> other manufactures devices to use this code.
> >>> I didn't check all NAND devices, of course. But devices which i know
> >>> have identical memory arrangements and general access methods. They
> >>> differs only access times which is adjusted by platform code. Moreover,
> >>> Linux NAND driver doesn't distinguish between different manufacturers.
> >>> So i think this driver should work with different manufacturers devices.
> >>>
> >>> If this statement is true the ECC and bad block management algorithms
> >>> depend of NAND page size only. This driver support only small page (256
> >>> or 512 bytes), but can be modified to support large page in the future
> >>> (device with large page has other command set).
> >>>
> >>> Other issue is 16-bit bus width support. It's not difficult to add this
> >>> feature (add 3 small functions), but i cannot test it because have 8-bit
> >>> flash only.
> >>>
> >>>> You say this is not compatible with Linux. How much effort is required
> >>>> to make it compatible? A lot of people use eCos for RedBoot, booting
> >>>> Linux. In this situation it is useful to be compatible with Linux.
> >>> Unfortunately Linux NAND driver has complex bad block management
> >>> algorithm and the best way to make driver compatible with Linux - get
> >>> code from it (this is that u-boot does). Therefore if i use other bbm
> >>> algorithm, it doesn't matter to use the same ECC algorithm, more so i
> >>> didn't find its description.
> >>>
> >>> You can find more information about Linux NAND driver there:
> >>> http://www.linux-mtd.infradead.org/doc/nand.html
> >>> http://www.linux-mtd.infradead.org/tech/mtdnand/index.html
> >>>
> >>> There are other reasons in using especial bbm algorithm.
> >>> eCos flash API doesn't have methods to works with NAND speciality (write
> >>> to spare area, check bad blocks and etc.) and RedBoot doesn't support
> >>> this features too. This driver hides NAND flash particularity and makes
> >>> it transparent for flash API and RedBoot FIS.
> >>>
> >>> Maybe somebody has other opinion. You are welcome! ;-)
> >> I've not had time to review this, but how different is it from
> >> the existing Toshiba NAND device driver?
> > 
> > In general:
> > 
> >  - It supports not only Toshiba chips.
> 
> Good.  Does it support the newer chips which have 4KB pages?

Not yet. But there are no barriers to add it in the future.

> >  - It has own ECC code (not from Linux and so not GPL-infected).
> 
> As Andrew has said, to really be useful, the ECC management must be
> compatible (if not borrowed from) Linux.

It doesn't have sense if driver doesn't use the same bad block
management algorithm.

> >  - It has page buffer in RAM so application can read any part of page
> > and doesn't worry about ECC (driver reads whole page and corrects data).
> > Buffer also allows to read data from one page several times without
> > access to chip.
> 
> We already have a FLASH driver function for this (flash_read_buffer())
> Why have two implementations?

I don't completely understand what you mean. My driver implements just
this function (if you mean flash_read_buf()), but it uses RAM buffer for
reading page, because ECC can be calculated for whole page only.

E.g. Toshiba NAND driver doesn't calculate ECC if application reads part
of page and therefore can read with error.

> >  - It implements bad block management algorithm which reserves repair
> > area at the end of the flash and replace bad blocks in main area with
> > blocks from it. New bad blocks will be also replaced. Management
> > information resides in last not bad block.
> 
> Again, is this compatible with how Linux does it?

No. There are many reasons why not.

Linux bad block management algorithm cannot be convenient with current
eCos flash API. RedBoot and eCos application don't know anything about
bad blocks and other NAND characteristics.

The one opportunity to use Linux compatible driver in eCos is using
JFFS2 (it knows about bad blocks). But JFFS2 cannot use eCos flash API,
because it must have access to NAND special functions (for example, it
writes to spare area).

> Virtually all "complex" platforms may end up running Linux at
> one time or another, so we should strive to be as supportive
> (compatible) as possible.  If your driver can be seen as an
> upgrade to the existing driver(s), then this would be best
> as having multiple solutions only causes grief...

I think there are two NAND driver development directions. The first is
using eCos flash API and not Linux compatible driver, which hides NAND
particularity. The second is to create flash_V3 branch, finish JFFS2 and
write compatible with Linux driver. And these directions don't prohibit
each other.

I use first direction because i don't need Linux compatibility. If
anybody wants, he can choose other way.

Best regards
Alexey Shusharin


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: NAND Flash device driver
  2007-12-20 13:42             ` Alexey Shusharin
@ 2007-12-21  8:19               ` Alexey Shusharin
  0 siblings, 0 replies; 10+ messages in thread
From: Alexey Shusharin @ 2007-12-21  8:19 UTC (permalink / raw)
  To: Gary Thomas; +Cc: ecos-patches


> > Again, is this compatible with how Linux does it?
> 
> No. There are many reasons why not.
> 
> Linux bad block management algorithm cannot be convenient with current
> eCos flash API. RedBoot and eCos application don't know anything about
> bad blocks and other NAND characteristics.
> 
> The one opportunity to use Linux compatible driver in eCos is using
> JFFS2 (it knows about bad blocks). But JFFS2 cannot use eCos flash API,
> because it must have access to NAND special functions (for example, it
> writes to spare area).

Hi

I think i should give an example.
Let us assume that we have NAND flash with 4096 blocks and block #5 is
manufacturer marked as bad. What is happen if we create flash image in
first ten blocks (RedBoot command "fis create").

Toshiba NAND driver erases first ten blocks (and loses bad block marker
in block #5) and writes data there. So later we will lose information in
block #5.

Linux compatible driver just returns error, because block #5 is bad. It
assumes that application should check block before read/write/erase. So
if we use flash API and FIS we cannot use Linux compatible driver
without rewriting applications.

My NAND driver remaps block #5 to block from repair area (e.g. #4064).
Application doesn't know about remapping and thinks that writes to block
#5. So we can use this driver to work with FIS and eCos application uses
flash API.

Another situation if we use Linux compatible driver together with JFFS2.
Then NAND driver has special NAND API that is used by JFFS2. And
application should use file system API instead flash API.

So my NAND driver is not compatible with Linux, but compatible with FIS
and flash API. On the other hand Linux compatible driver will be not
compatible with FIS. I prefer have both for different tasks, but one is
good too.

Best regards
Alexey Shusharin


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-12-21  8:19 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-10 13:01 NAND Flash device driver Alexey Shusharin
2007-12-18  4:02 ` Alexey Shusharin
2007-12-18  9:13   ` Andrew Lunn
2007-12-18 10:37     ` Alexey Shusharin
2007-12-18 14:30       ` Gary Thomas
2007-12-18 15:17         ` Alexey Shusharin
2007-12-20 12:11           ` Gary Thomas
2007-12-20 12:35             ` Jonathan Larmour
2007-12-20 13:42             ` Alexey Shusharin
2007-12-21  8:19               ` Alexey Shusharin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).