diff -urN a/common/main.c b/common/main.c
--- a/common/main.c     2010-09-29 01:20:55.000000000 +0400
+++ b/common/main.c     2011-03-02 23:34:12.000000000 +0300
@@ -56,9 +56,9 @@

  extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char * 
const argv[]);

-#if defined(CONFIG_UPDATE_TFTP)
-void update_tftp (void);
-#endif /* CONFIG_UPDATE_TFTP */
+#if defined(CONFIG_UPDITB)
+void update_itb (void);
+#endif /* CONFIG_UPDITB */

  #define MAX_DELAY_STOP_STR 32

@@ -365,9 +365,9 @@
         }
  #endif /* CONFIG_PREBOOT */

-#if defined(CONFIG_UPDATE_TFTP)
-       update_tftp ();
-#endif /* CONFIG_UPDATE_TFTP */
+#if defined(CONFIG_UPDITB)
+       update_itb ();
+#endif /* CONFIG_UPDITB */

  #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
         s = getenv ("bootdelay");
diff -urN a/common/Makefile b/common/Makefile
--- a/common/Makefile   2010-09-29 01:20:55.000000000 +0400
+++ b/common/Makefile   2011-03-02 23:34:12.000000000 +0300
@@ -164,7 +164,7 @@
  COBJS-$(CONFIG_LCD) += lcd.o
  COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
  COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
-COBJS-$(CONFIG_UPDATE_TFTP) += update.o
+COBJS-$(CONFIG_UPDITB) += upditb.o
  COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o


diff -urN a/common/update.c b/common/update.c
--- a/common/update.c   2011-02-28 15:46:10.000000000 +0300
+++ b/common/update.c   1970-01-01 03:00:00.000000000 +0300
@@ -1,315 +0,0 @@
-/*
- * (C) Copyright 2008 Semihalf
- *
- * Written by: Rafal Czubak <rcz@semihalf.com>
- *             Bartlomiej Sieka <tur@semihalf.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-
-#include <common.h>
-
-#if !(defined(CONFIG_FIT) && defined(CONFIG_OF_LIBFDT))
-#error "CONFIG_FIT and CONFIG_OF_LIBFDT are required for auto-update 
feature"
-#endif
-
-#if defined(CONFIG_SYS_NO_FLASH)
-#error "CONFIG_SYS_NO_FLASH defined, but FLASH is required for 
auto-update feature"
-#endif
-
-#include <command.h>
-#include <flash.h>
-#include <net.h>
-#include <malloc.h>
-
-/* env variable holding the location of the update file */
-#define UPDATE_FILE_ENV                "updatefile"
-
-/* set configuration defaults if needed */
-#ifndef CONFIG_UPDATE_LOAD_ADDR
-#define CONFIG_UPDATE_LOAD_ADDR        0x100000
-#endif
-
-#ifndef CONFIG_UPDATE_TFTP_MSEC_MAX
-#define CONFIG_UPDATE_TFTP_MSEC_MAX    100
-#endif
-
-#ifndef CONFIG_UPDATE_TFTP_CNT_MAX
-#define CONFIG_UPDATE_TFTP_CNT_MAX     0
-#endif
-
-extern ulong TftpRRQTimeoutMSecs;
-extern int TftpRRQTimeoutCountMax;
-extern flash_info_t flash_info[];
-extern ulong load_addr;
-
-static uchar *saved_prot_info;
-
-static int update_load(char *filename, ulong msec_max, int cnt_max, 
ulong addr)
-{
-       int size, rv;
-       ulong saved_timeout_msecs;
-       int saved_timeout_count;
-       char *saved_netretry, *saved_bootfile;
-
-       rv = 0;
-       /* save used globals and env variable */
-       saved_timeout_msecs = TftpRRQTimeoutMSecs;
-       saved_timeout_count = TftpRRQTimeoutCountMax;
-       saved_netretry = strdup(getenv("netretry"));
-       saved_bootfile = strdup(BootFile);
-
-       /* set timeouts for auto-update */
-       TftpRRQTimeoutMSecs = msec_max;
-       TftpRRQTimeoutCountMax = cnt_max;
-
-       /* we don't want to retry the connection if errors occur */
-       setenv("netretry", "no");
-
-       /* download the update file */
-       load_addr = addr;
-       copy_filename(BootFile, filename, sizeof(BootFile));
-       size = NetLoop(TFTP);
-
-       if (size < 0)
-               rv = 1;
-       else if (size > 0)
-               flush_cache(addr, size);
-
-       /* restore changed globals and env variable */
-       TftpRRQTimeoutMSecs = saved_timeout_msecs;
-       TftpRRQTimeoutCountMax = saved_timeout_count;
-
-       setenv("netretry", saved_netretry);
-       if (saved_netretry != NULL)
-               free(saved_netretry);
-
-       if (saved_bootfile != NULL) {
-               copy_filename(BootFile, saved_bootfile, sizeof(BootFile));
-               free(saved_bootfile);
-       }
-
-       return rv;
-}
-
-static int update_flash_protect(int prot, ulong addr_first, ulong 
addr_last)
-{
-       uchar *sp_info_ptr;
-       ulong s;
-       int i, bank, cnt;
-       flash_info_t *info;
-
-       sp_info_ptr = NULL;
-
-       if (prot == 0) {
-               saved_prot_info =
-                       calloc(CONFIG_SYS_MAX_FLASH_BANKS * 
CONFIG_SYS_MAX_FLASH_SECT, 1);
-               if (!saved_prot_info)
-                       return 1;
-       }
-
-       for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
-               cnt = 0;
-               info = &flash_info[bank];
-
-               /* Nothing to do if the bank doesn't exist */
-               if (info->sector_count == 0)
-                       return 0;
-
-               /* Point to current bank protection information */
-               sp_info_ptr = saved_prot_info + (bank * 
CONFIG_SYS_MAX_FLASH_SECT);
-
-               /*
-                * Adjust addr_first or addr_last if we are on bank 
boundary.
-                * Address space between banks must be continuous for other
-                * flash functions (like flash_sect_erase or flash_write) to
-                * succeed. Banks must also be numbered in correct order,
-                * according to increasing addresses.
-                */
-               if (addr_last > info->start[0] + info->size - 1)
-                       addr_last = info->start[0] + info->size - 1;
-               if (addr_first < info->start[0])
-                       addr_first = info->start[0];
-
-               for (i = 0; i < info->sector_count; i++) {
-                       /* Save current information about protected 
sectors */
-                       if (prot == 0) {
-                               s = info->start[i];
-                               if ((s >= addr_first) && (s <= addr_last))
-                                       sp_info_ptr[i] = info->protect[i];
-
-                       }
-
-                       /* Protect/unprotect sectors */
-                       if (sp_info_ptr[i] == 1) {
-#if defined(CONFIG_SYS_FLASH_PROTECTION)
-                               if (flash_real_protect(info, i, prot))
-                                       return 1;
-#else
-                               info->protect[i] = prot;
-#endif
-                               cnt++;
-                       }
-               }
-
-               if (cnt) {
-                       printf("%sProtected %d sectors\n",
-                                               prot ? "": "Un-", cnt);
-               }
-       }
-
-       if((prot == 1) && saved_prot_info)
-               free(saved_prot_info);
-
-       return 0;
-}
-
-static int update_flash(ulong addr_source, ulong addr_first, ulong size)
-{
-       ulong addr_last = addr_first + size - 1;
-
-       /* round last address to the sector boundary */
-       if (flash_sect_roundb(&addr_last) > 0)
-               return 1;
-
-       if (addr_first >= addr_last) {
-               printf("Error: end address exceeds addressing space\n");
-               return 1;
-       }
-
-       /* remove protection on processed sectors */
-       if (update_flash_protect(0, addr_first, addr_last) > 0) {
-               printf("Error: could not unprotect flash sectors\n");
-               return 1;
-       }
-
-       printf("Erasing 0x%08lx - 0x%08lx", addr_first, addr_last);
-       if (flash_sect_erase(addr_first, addr_last) > 0) {
-               printf("Error: could not erase flash\n");
-               return 1;
-       }
-
-       printf("Copying to flash...");
-       if (flash_write((char *)addr_source, addr_first, size) > 0) {
-               printf("Error: could not copy to flash\n");
-               return 1;
-       }
-       printf("done\n");
-
-       /* enable protection on processed sectors */
-       if (update_flash_protect(1, addr_first, addr_last) > 0) {
-               printf("Error: could not protect flash sectors\n");
-               return 1;
-       }
-
-       return 0;
-}
-
-static int update_fit_getparams(const void *fit, int noffset, ulong *addr,
-                                               ulong *fladdr, ulong *size)
-{
-       const void *data;
-
-       if (fit_image_get_data(fit, noffset, &data, (size_t *)size))
-               return 1;
-
-       if (fit_image_get_load(fit, noffset, (ulong *)fladdr))
-               return 1;
-
-       *addr = (ulong)data;
-
-       return 0;
-}
-
-void update_tftp(void)
-{
-       char *filename, *env_addr;
-       int images_noffset, ndepth, noffset;
-       ulong update_addr, update_fladdr, update_size;
-       ulong addr;
-       void *fit;
-
-       printf("Auto-update from TFTP: ");
-
-       /* get the file name of the update file */
-       filename = getenv(UPDATE_FILE_ENV);
-       if (filename == NULL) {
-               printf("failed, env. variable '%s' not found\n",
-                                                       UPDATE_FILE_ENV);
-               return;
-       }
-
-       printf("trying update file '%s'\n", filename);
-
-       /* get load address of downloaded update file */
-       if ((env_addr = getenv("loadaddr")) != NULL)
-               addr = simple_strtoul(env_addr, NULL, 16);
-       else
-               addr = CONFIG_UPDATE_LOAD_ADDR;
-
-
-       if (update_load(filename, CONFIG_UPDATE_TFTP_MSEC_MAX,
-                                       CONFIG_UPDATE_TFTP_CNT_MAX, addr)) {
-               printf("Can't load update file, aborting auto-update\n");
-               return;
-       }
-
-       fit = (void *)addr;
-
-       if (!fit_check_format((void *)fit)) {
-               printf("Bad FIT format of the update file, aborting "
-                                                       "auto-update\n");
-               return;
-       }
-
-       /* process updates */
-       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
-
-       ndepth = 0;
-       noffset = fdt_next_node(fit, images_noffset, &ndepth);
-       while (noffset >= 0 && ndepth > 0) {
-               if (ndepth != 1)
-                       goto next_node;
-
-               printf("Processing update '%s' :",
-                       fit_get_name(fit, noffset, NULL));
-
-               if (!fit_image_check_hashes(fit, noffset)) {
-                       printf("Error: invalid update hash, aborting\n");
-                       goto next_node;
-               }
-
-               printf("\n");
-               if (update_fit_getparams(fit, noffset, &update_addr,
- &update_fladdr, &update_size)) {
-                       printf("Error: can't get update parameteres, "
-                                                               
"aborting\n");
-                       goto next_node;
-               }
-               if (update_flash(update_addr, update_fladdr, update_size)) {
-                       printf("Error: can't flash update (%ld %ld %ld), 
aborting\n", update_addr, update_fladdr, update_size);
-                       goto next_node;
-               }
-next_node:
-               noffset = fdt_next_node(fit, noffset, &ndepth);
-       }
-
-       return;
-}
diff -urN a/common/upditb.c b/common/upditb.c
--- a/common/upditb.c   1970-01-01 03:00:00.000000000 +0300
+++ b/common/upditb.c   2011-03-07 16:27:02.000000000 +0300
@@ -0,0 +1,556 @@
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * Written by: Rafal Czubak <rcz@semihalf.com>
+ *             Bartlomiej Sieka <tur@semihalf.com>
+ *
+ * (C) Copyright 2011 Tibbo Tech.
+ * Code refactoring, Cmd and Nand load/save features:
+ *     Dvorkin Dmitry <dvorkin@tibbo.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+
+#if !(defined(CONFIG_FIT) && defined(CONFIG_OF_LIBFDT))
+#error "CONFIG_FIT and CONFIG_OF_LIBFDT are required for auto-update 
feature"
+#endif
+
+#include <command.h>
+#if !defined(CONFIG_SYS_NO_FLASH)
+#include <flash.h>
+#endif
+#if defined(CONFIG_CMD_NAND)
+#include <nand.h>
+#endif
+#include <net.h>
+#include <malloc.h>
+
+/* env variable holding the location of the update file */
+#define UPDATE_FILE_ENV                "updatefile"
+
+/* set configuration defaults if needed */
+#ifndef CONFIG_UPDITB_LOAD_ADDR
+#define CONFIG_UPDITB_LOAD_ADDR        0x100000
+#endif
+
+#ifndef CONFIG_UPDITB_TFTP_MSEC_MAX
+#define CONFIG_UPDITB_TFTP_MSEC_MAX    100
+#endif
+
+#ifndef CONFIG_UPDITB_TFTP_CNT_MAX
+#define CONFIG_UPDITB_TFTP_CNT_MAX     0
+#endif
+
+extern ulong TftpRRQTimeoutMSecs;
+extern int TftpRRQTimeoutCountMax;
+extern flash_info_t flash_info[];
+extern ulong load_addr;
+
+extern int run_command (const char *cmd, int flag);
+
+static uchar *saved_prot_info;
+
+enum XLAT_ST {
+ XLAT_ST_D,    /* default */
+ XLAT_ST_S,    /* skip \ */
+ XLAT_ST_B,    /* begin attr name */
+ XLAT_ST_A,    /* in attr name */
+ XLAT_ST_s,    /* skip \} in attr name */
+ XLAT_ST_E,    /* end attr name */
+};
+
+enum XLAT_CT {
+ XLAT_CT_DEF,
+ XLAT_CT_BKS,
+ XLAT_CT_BEG,
+ XLAT_CT_END,
+};
+
+enum XLAT_ST xlat_st_tbl[ 6][ 4] = {
+ // def       \\         {          }
+ { XLAT_ST_D, XLAT_ST_S, XLAT_ST_B, XLAT_ST_D }, // _ST_D
+ { XLAT_ST_D, XLAT_ST_D, XLAT_ST_D, XLAT_ST_D }, // _ST_S
+ { XLAT_ST_A, XLAT_ST_A, XLAT_ST_A, XLAT_ST_E }, // _ST_B
+ { XLAT_ST_A, XLAT_ST_s, XLAT_ST_A, XLAT_ST_E }, // _ST_A
+ { XLAT_ST_A, XLAT_ST_A, XLAT_ST_A, XLAT_ST_A }, // _ST_s
+ { XLAT_ST_D, XLAT_ST_S, XLAT_ST_B, XLAT_ST_D }, // _ST_E
+};
+
+typedef char *( *xlat_cfpt)( void *_data, char *_as, ulong _al, ulong 
*_rlen);
+
+static int Xlat_R( const char *_i, ulong _il, char *_o, ulong _ol,
+    xlat_cfpt _cfp, void *_data) {
+ ulong i = -1, oi = 0;
+ ulong rlen, ret = 0;
+ char *tks;
+ ulong tkl;
+ char *repl_av = NULL;
+ unsigned char c;
+ enum XLAT_CT ctype;
+ enum XLAT_ST curst = XLAT_ST_D;
+
+ tks = NULL;  tkl = 0;
+ while ( ++i < _il && ( c = _i[ i]) != '\0') {
+//printf( "x:%d\n", i);
+   ctype = XLAT_CT_DEF;
+   if ( c == '\\') ctype = XLAT_CT_BKS;
+   if ( c == '{' ) ctype = XLAT_CT_BEG;
+   if ( c == '}' ) ctype = XLAT_CT_END;
+   curst = xlat_st_tbl[ curst][ ctype];
+   switch ( curst) {
+     case XLAT_ST_s:
+     case XLAT_ST_S:  break;
+     case XLAT_ST_D:  if ( _o) _o[ oi++] = c;  break;
+     case XLAT_ST_B:  tks = ( _i + i + 1);  tkl = 0;  break;
+     case XLAT_ST_A:  tkl++;  break;
+     case XLAT_ST_E:
+//       printf( "AVP:%s\n", tmp_attr);
+       // macro name ended
+       ret++;
+       // if output buffer == NULL - return number of potential subs
+       if ( !_o) break;
+       repl_av = NULL;  rlen = 0;
+       if ( _cfp) repl_av = _cfp( _data, tks, tkl, &rlen);
+       // actually replace
+       if ( repl_av != NULL) {  memcpy( _o + oi, repl_av, rlen);  oi += 
rlen;  }
+       // if replace to NULL
+       if ( repl_av == NULL && rlen > 0) break;
+       // if no replace found - copy {text} to output - safe for future
+       if ( repl_av == NULL && rlen < 1) {
+         _o[ oi++] = '{';
+         memcpy( _o + oi, tks, tkl);  oi += tkl;
+         _o[ oi++] = '}';  }
+       break;
+   } // end of switch
+   if ( tkl >= _ol) return( ret);
+ }
+ return( ret);  }
+
+static int update_load_tftp(char *filename, ulong addr)
+{
+       int size, rv;
+       ulong msec_max = CONFIG_UPDITB_TFTP_MSEC_MAX;
+       int cnt_max = CONFIG_UPDITB_TFTP_CNT_MAX;
+       ulong saved_timeout_msecs;
+       int saved_timeout_count;
+       char *saved_netretry, *saved_bootfile;
+
+       rv = 0;
+       /* save used globals and env variable */
+       saved_timeout_msecs = TftpRRQTimeoutMSecs;
+       saved_timeout_count = TftpRRQTimeoutCountMax;
+       saved_netretry = strdup(getenv("netretry"));
+       saved_bootfile = strdup(BootFile);
+
+       /* set timeouts for auto-update */
+       TftpRRQTimeoutMSecs = msec_max;
+       TftpRRQTimeoutCountMax = cnt_max;
+
+       /* we don't want to retry the connection if errors occur */
+       setenv("netretry", "no");
+
+       /* download the update file */
+       load_addr = addr;
+       copy_filename(BootFile, filename, sizeof(BootFile));
+       size = NetLoop(TFTP);
+
+       if (size < 0)
+               rv = 1;
+       else if (size > 0)
+               flush_cache(addr, size);
+
+       /* restore changed globals and env variable */
+       TftpRRQTimeoutMSecs = saved_timeout_msecs;
+       TftpRRQTimeoutCountMax = saved_timeout_count;
+
+       setenv("netretry", saved_netretry);
+       if (saved_netretry != NULL)
+               free(saved_netretry);
+
+       if (saved_bootfile != NULL) {
+               copy_filename(BootFile, saved_bootfile, sizeof(BootFile));
+               free(saved_bootfile);
+       }
+
+       return rv;
+}
+
+typedef struct Xlate_load_T {
+ char *file;
+ ulong load_to;
+} Xlate_load_t;
+
+char *Xlate_load( void *_data, char *_as, ulong _al, ulong *_rlen) {
+ Xlate_load_t *Xdp = ( Xlate_load_t *)_data;
+ char xs[ 64];
+ memset( xs, 0, 64);
+ if ( _al == 4 && memcmp( _as, "file", 4) == 0) sprintf( xs, "%s", 
Xdp->file);
+ if ( _al == 7 && memcmp( _as, "load_to", 7) == 0) sprintf( xs, 
"0x%08x", Xdp->load_to);
+ *_rlen = strlen( xs);
+ return( xs);  }
+
+static int update_load_cmd( char *_file, ulong _addr) {
+ char *cmd;
+ char cmdx[ 1024];
+ Xlate_load_t Xd = { .file = _file, .load_to = _addr };
+ if ( ( cmd = getenv( "upditb_cmd_load_pre")) != NULL) {
+   memset( cmdx, 0, 1024);
+   Xlat_R( cmd, strlen( cmd), cmdx, 1024, Xlate_load, &Xd);
+   printf( "Preload cmd template:%s\n", cmd);
+   printf( "Xlated to:%s\n", cmdx);
+   /* prepare for loading into RAM, 'usb start' for ex. */
+   if ( run_command( cmdx, 0) == -1) return( 1);
+ }
+ /* load to RAM. 'fatload usb 0:1 <address> <file>' for ex. */
+ if ( ( cmd = getenv( "upditb_cmd_load")) != NULL) {
+   memset( cmdx, 0, 1024);
+   Xlat_R( cmd, strlen( cmd), cmdx, 1024, Xlate_load, &Xd);
+   printf( "Load cmd template:%s\n", cmd);
+   printf( "Xlated to:%s\n", cmdx);
+   /* prepare for loading into RAM, 'usb start' for ex. */
+   if ( run_command( cmdx, 0) == -1) return( 1);
+ }
+ return( 0); }
+
+typedef struct Xlate_flash_T {
+ ulong a_src;
+ ulong a_dst;
+ ulong size;
+} Xlate_flash_t;
+
+char *Xlate_flash( void *_data, char *_as, ulong _al, ulong *_rlen) {
+ Xlate_flash_t *Xdp = ( Xlate_flash_t *)_data;
+ char xs[ 64];
+ memset( xs, 0, 64);
+ if ( _al == 8 && memcmp( _as, "addr_src", 8) == 0) sprintf( xs, 
"0x%08x", Xdp->a_src);
+ if ( _al == 8 && memcmp( _as, "addr_dst", 8) == 0) sprintf( xs, 
"0x%08x", Xdp->a_dst);
+ if ( _al == 8 && memcmp( _as, "img_size", 8) == 0) sprintf( xs, 
"0x%08x", Xdp->size);
+ *_rlen = strlen( xs);
+ return( xs);  }
+
+static int update_s_cmd( ulong _addr_source, ulong _addr_first, ulong 
_size) {
+ char *cmdc;
+ char cmdcx[ 1024];
+ Xlate_flash_t Xd = { .a_src = _addr_source, .a_dst = _addr_first, 
.size = _size };
+ printf( "%s()\n", __FUNCTION__);
+ if ( ( cmdc = getenv( "upditb_cmd_save")) == NULL) return( 1);
+ memset( cmdcx, 0, 1024);
+ Xlat_R( cmdc, strlen( cmdc), cmdcx, 1024, Xlate_flash, &Xd);
+ printf( "Save cmd template:%s\n", cmdc);
+ printf( "Xlated to:%s\n", cmdcx);
+ /* save to target, nand write {addr_src} {addr_dst} {img_size} for ex. */
+ if ( run_command( cmdcx, 0) == -1) return( 1);
+ return( 0); }
+
+#if !defined(CONFIG_SYS_NO_FLASH)
+static int update_flash_protect(int prot, ulong addr_first, ulong 
addr_last)
+{
+       uchar *sp_info_ptr;
+       ulong s;
+       int i, bank, cnt;
+       flash_info_t *info;
+
+       sp_info_ptr = NULL;
+
+       if (prot == 0) {
+               saved_prot_info =
+                       calloc(CONFIG_SYS_MAX_FLASH_BANKS * 
CONFIG_SYS_MAX_FLASH_SECT, 1);
+               if (!saved_prot_info)
+                       return 1;
+       }
+
+       for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
+               cnt = 0;
+               info = &flash_info[bank];
+
+               /* Nothing to do if the bank doesn't exist */
+               if (info->sector_count == 0)
+                       return 0;
+
+               /* Point to current bank protection information */
+               sp_info_ptr = saved_prot_info + (bank * 
CONFIG_SYS_MAX_FLASH_SECT);
+
+               /*
+                * Adjust addr_first or addr_last if we are on bank 
boundary.
+                * Address space between banks must be continuous for other
+                * flash functions (like flash_sect_erase or flash_write) to
+                * succeed. Banks must also be numbered in correct order,
+                * according to increasing addresses.
+                */
+               if (addr_last > info->start[0] + info->size - 1)
+                       addr_last = info->start[0] + info->size - 1;
+               if (addr_first < info->start[0])
+                       addr_first = info->start[0];
+
+               for (i = 0; i < info->sector_count; i++) {
+                       /* Save current information about protected 
sectors */
+                       if (prot == 0) {
+                               s = info->start[i];
+                               if ((s >= addr_first) && (s <= addr_last))
+                                       sp_info_ptr[i] = info->protect[i];
+
+                       }
+
+                       /* Protect/unprotect sectors */
+                       if (sp_info_ptr[i] == 1) {
+#if defined(CONFIG_SYS_FLASH_PROTECTION)
+                               if (flash_real_protect(info, i, prot))
+                                       return 1;
+#else
+                               info->protect[i] = prot;
+#endif
+                               cnt++;
+                       }
+               }
+
+               if (cnt) {
+                       printf("%sProtected %d sectors\n",
+                                               prot ? "": "Un-", cnt);
+               }
+       }
+
+       if((prot == 1) && saved_prot_info)
+               free(saved_prot_info);
+
+       return 0;
+}
+
+static int update_s_flash(ulong addr_source, ulong addr_first, ulong size)
+{
+       ulong addr_last = addr_first + size - 1;
+
+       printf( "%s()\n", __FUNCTION__);
+       /* round last address to the sector boundary */
+       if (flash_sect_roundb(&addr_last) > 0)
+               return 1;
+
+       if (addr_first >= addr_last) {
+               printf("Error: end address exceeds addressing space\n");
+               return 1;
+       }
+
+       /* remove protection on processed sectors */
+       if (update_flash_protect(0, addr_first, addr_last) > 0) {
+               printf("Error: could not unprotect flash sectors\n");
+               return 1;
+       }
+
+       printf("Erasing 0x%08lx - 0x%08lx", addr_first, addr_last);
+       if (flash_sect_erase(addr_first, addr_last) > 0) {
+               printf("Error: could not erase flash\n");
+               return 1;
+       }
+
+       printf("Copying to flash...");
+       if (flash_write((char *)addr_source, addr_first, size) > 0) {
+               printf("Error: could not copy to flash\n");
+               return 1;
+       }
+       printf("done\n");
+
+       /* enable protection on processed sectors */
+       if (update_flash_protect(1, addr_first, addr_last) > 0) {
+               printf("Error: could not protect flash sectors\n");
+               return 1;
+       }
+
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_NAND)
+static int update_s_nand( ulong _a_src, ulong _a_dst, size_t _size)
+{
+ int err;
+ size_t len = _size;
+ size_t tl;
+ tl = nand_info[ 0].writesize;
+ printf( "%s()\n", __FUNCTION__);
+ if ( ( _size % tl) != 0) {
+   printf( "padding %d with %d bytes\n", _size, ( tl - ( _size % tl)));
+   len = _size += ( tl - ( _size % tl));
+   printf( "new size is %d bytes\n", _size);
+ }
+ err = nand_write_skip_bad( &nand_info[ 0], _a_dst, &len, _a_src);
+ if ( err != 0) return( 1);
+ return( 0);  }
+#endif
+
+static int update_fit_getparams(const void *fit, int noffset, ulong *addr,
+                                               ulong *fladdr, ulong *size)
+{
+       const void *data;
+
+       if (fit_image_get_data(fit, noffset, &data, (size_t *)size))
+               return 1;
+
+       if (fit_image_get_load(fit, noffset, (ulong *)fladdr))
+               return 1;
+
+       *addr = (ulong)data;
+
+       return 0;
+}
+
+void update_itb(void)
+{
+       char *filename, *env_addr;
+       char *method_load, *method_save, *ts;
+       int images_noffset, ndepth, noffset;
+       ulong update_addr, update_fladdr, update_size;
+       ulong addr;
+       void *fit;
+       int err, sl;
+
+       /* update method: tftp or something else */
+       ts = method_load = getenv( "upditb_load_method");
+       if ( method_load == NULL) method_load = "none";
+       printf( "Auto-update ITB load method:%s\n", method_load);
+       if ( ts == NULL) return;
+       method_save = getenv( "upditb_save_method");
+       if ( method_save == NULL) method_save = "flash";
+
+       /* get the file name of the update file */
+       filename = getenv(UPDATE_FILE_ENV);
+       if (filename == NULL) {
+               printf("failed, env. variable '%s' not found\n",
+                                                       UPDATE_FILE_ENV);
+               return;
+       }
+
+       printf("trying update file '%s'\n", filename);
+#ifdef CONFIG_LCD
+       lcd_printf( "Loading auto-update file '%s'...", filename);
+#endif
+
+       /* get load address of downloaded update file */
+       if ((env_addr = getenv("loadaddr")) != NULL)
+               addr = simple_strtoul(env_addr, NULL, 16);
+       else
+               addr = CONFIG_UPDITB_LOAD_ADDR;
+
+       err = -1;
+       sl = strlen( method_load);
+       if ( sl == 4 && strcmp( method_load, "tftp") == 0) err = 
update_load_tftp( filename, addr);
+       if ( sl == 3 && strcmp( method_load, "cmd" ) == 0) err = 
update_load_cmd(  filename, addr);
+       switch ( err) {
+         case -1:
+#ifdef CONFIG_LCD
+           lcd_printf( "ERR-1\n");
+#endif
+           printf( "No such method '%s', aborting auto-update\n", 
method_load);
+           return;
+           break;
+         case 0:       /* it's OK */
+#ifdef CONFIG_LCD
+           lcd_printf( "OK\n");
+#endif
+           break;
+         default:
+#ifdef CONFIG_LCD
+           lcd_printf( "ERR\n");
+#endif
+           printf( "Can't load update file, aborting auto-update\n");
+           return;
+           break;
+       }
+
+#ifdef CONFIG_LCD
+       lcd_printf( "Auto-update file is loaded, checking...");
+#endif
+       fit = (void *)addr;
+
+       if (!fit_check_format((void *)fit)) {
+               printf("Bad FIT format of the update file, aborting "
+                                                       "auto-update\n");
+#ifdef CONFIG_LCD
+       lcd_printf( "ERR\n");
+#endif
+               return;
+       }
+#ifdef CONFIG_LCD
+       lcd_printf( "OK\n");
+#endif
+
+       /* process updates */
+       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+
+#ifdef CONFIG_LCD
+       err = fit_get_desc( fit, 0, &ts);
+       if ( err) ts = "(no description)";
+       lcd_printf( "Processing %s...\n", ts);
+#endif
+fit_print_contents( (void *)fit);
+       ndepth = 0;
+       noffset = fdt_next_node(fit, images_noffset, &ndepth);
+       while (noffset >= 0 && ndepth > 0) {
+               if (ndepth != 1)
+                       goto next_node;
+
+               printf("Processing update '%s' :",
+                       fit_get_name(fit, noffset, NULL));
+
+               if (!fit_image_check_hashes(fit, noffset)) {
+                       printf("Error: invalid update hash, aborting\n");
+                       goto next_node;
+               }
+
+               printf("\n");
+               if (update_fit_getparams(fit, noffset, &update_addr,
+ &update_fladdr, &update_size)) {
+                       printf("Error: can't get update parameteres, "
+                                                               
"aborting\n");
+                       goto next_node;
+               }
+fit_image_print( fit, noffset, "");
+#ifdef CONFIG_LCD
+               err = fit_get_desc( fit, noffset, &ts);
+               if ( err) ts = "(no description)";
+               lcd_printf( "Flashing %s...", ts);
+#endif
+               sl = strlen( method_save);
+               err = -1;
+#if !defined(CONFIG_SYS_NO_FLASH)
+               if ( sl == 5 && strcmp( method_save, "flash") == 0) err 
= update_s_flash(update_addr, update_fladdr, update_size);
+#endif
+               if ( sl == 3 && strcmp( method_save, "cmd" ) == 0) err = 
update_s_cmd( update_addr, update_fladdr, update_size);
+#if defined(CONFIG_CMD_NAND)
+               if ( sl == 4 && strcmp( method_save, "nand") == 0) err = 
update_s_nand(update_addr, update_fladdr, update_size);
+#endif
+               /* fallback if method not found */
+               if ( err == -1) err = update_s_flash(update_addr, 
update_fladdr, update_size);
+               if ( err) {
+                       printf("Error: can't flash update (%ld %ld %ld), 
aborting\n", update_addr, update_fladdr, update_size);
+#ifdef CONFIG_LCD
+                       lcd_printf( "ERR\n");
+#endif
+                       goto next_node;
+               }
+#ifdef CONFIG_LCD
+               lcd_printf( "OK\n");
+#endif
+next_node:
+               noffset = fdt_next_node(fit, noffset, &ndepth);
+       }
+
+       return;
+}
diff -urN a/README b/README
--- a/README    2010-09-29 01:20:55.000000000 +0400
+++ b/README    2011-03-02 23:34:12.000000000 +0300
@@ -2108,10 +2108,11 @@
   -150  common/cmd_nand.c       Incorrect FIT image format
    151  common/cmd_nand.c       FIT image format OK

-- Automatic software updates via TFTP server
-               CONFIG_UPDATE_TFTP
-               CONFIG_UPDATE_TFTP_CNT_MAX
-               CONFIG_UPDATE_TFTP_MSEC_MAX
+- Automatic software updates via ITB structure
+               CONFIG_UPDITB
+               CONFIG_UPDITB_TFTP
+               CONFIG_UPDITB_TFTP_CNT_MAX
+               CONFIG_UPDITB_TFTP_MSEC_MAX

                 These options enable and control the auto-update feature;
                 for a more detailed description refer to doc/README.update.
