#ifdef CONFIG_HAS_DATAFLASH
 #include <dataflash.h>
 #endif
+#include <hash.h>
 #include <watchdog.h>
 #include <asm/io.h>
 #include <linux/compiler.h>
 
 #ifdef CONFIG_CMD_CRC32
 
-#ifndef CONFIG_CRC32_VERIFY
-
 static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       ulong addr, length;
-       ulong crc;
-       ulong *ptr;
-
-       if (argc < 3)
-               return CMD_RET_USAGE;
-
-       addr = simple_strtoul (argv[1], NULL, 16);
-       addr += base_address;
-
-       length = simple_strtoul (argv[2], NULL, 16);
-
-       crc = crc32_wd (0, (const uchar *) addr, length, CHUNKSZ_CRC32);
-
-       printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
-                       addr, addr + length - 1, crc);
-
-       if (argc > 3) {
-               ptr = (ulong *) simple_strtoul (argv[3], NULL, 16);
-               *ptr = crc;
-       }
-
-       return 0;
-}
-
-#else  /* CONFIG_CRC32_VERIFY */
-
-int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       ulong addr, length;
-       ulong crc;
-       ulong *ptr;
-       ulong vcrc;
-       int verify;
+       int flags = 0;
        int ac;
        char * const *av;
 
-       if (argc < 3) {
-usage:
+       if (argc < 3)
                return CMD_RET_USAGE;
-       }
 
        av = argv + 1;
        ac = argc - 1;
+#ifdef CONFIG_HASH_VERIFY
        if (strcmp(*av, "-v") == 0) {
-               verify = 1;
+               flags |= HASH_FLAG_VERIFY;
                av++;
                ac--;
-               if (ac < 3)
-                       goto usage;
-       } else
-               verify = 0;
-
-       addr = simple_strtoul(*av++, NULL, 16);
-       addr += base_address;
-       length = simple_strtoul(*av++, NULL, 16);
-
-       crc = crc32_wd (0, (const uchar *) addr, length, CHUNKSZ_CRC32);
-
-       if (!verify) {
-               printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
-                               addr, addr + length - 1, crc);
-               if (ac > 2) {
-                       ptr = (ulong *) simple_strtoul (*av++, NULL, 16);
-                       *ptr = crc;
-               }
-       } else {
-               vcrc = simple_strtoul(*av++, NULL, 16);
-               if (vcrc != crc) {
-                       printf ("CRC32 for %08lx ... %08lx ==> %08lx != %08lx ** ERROR **\n",
-                                       addr, addr + length - 1, crc, vcrc);
-                       return 1;
-               }
        }
+#endif
 
-       return 0;
-
+       return hash_command("crc32", flags, cmdtp, flag, ac, av);
 }
-#endif /* CONFIG_CRC32_VERIFY */
 
 #endif
 
 
  * crypto could perhaps add named version of these algorithms here.
  */
 static struct hash_algo hash_algo[] = {
-#ifdef CONFIG_SHA1
+       /*
+        * This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since otherwise
+        * it bloats the code for boards which use SHA1 but not the 'hash'
+        * or 'sha1sum' commands.
+        */
+#ifdef CONFIG_CMD_SHA1SUM
        {
                "SHA1",
                SHA1_SUM_LEN,
                sha1_csum_wd,
                CHUNKSZ_SHA1,
        },
+#define MULTI_HASH
 #endif
 #ifdef CONFIG_SHA256
        {
                sha256_csum_wd,
                CHUNKSZ_SHA256,
        },
+#define MULTI_HASH
 #endif
+       {
+               "CRC32",
+               4,
+               crc32_wd_buf,
+               CHUNKSZ_CRC32,
+       },
 };
 
+#if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH)
+#define MULTI_HASH
+#endif
+
+/* Try to minimize code size for boards that don't want much hashing */
+#ifdef MULTI_HASH
+#define multi_hash()   1
+#else
+#define multi_hash()   0
+#endif
+
 /**
  * store_result: Store the resulting sum to an address or variable
  *
 int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
                 int argc, char * const argv[])
 {
-       struct hash_algo *algo;
        ulong addr, len;
-       u8 output[HASH_MAX_DIGEST_SIZE];
-       u8 vsum[HASH_MAX_DIGEST_SIZE];
 
        if (argc < 2)
                return CMD_RET_USAGE;
        addr = simple_strtoul(*argv++, NULL, 16);
        len = simple_strtoul(*argv++, NULL, 16);
 
-       algo = find_hash_algo(algo_name);
-       if (!algo) {
-               printf("Unknown hash algorithm '%s'\n", algo_name);
-               return CMD_RET_USAGE;
-       }
-       argc -= 2;
+       if (multi_hash()) {
+               struct hash_algo *algo;
+               u8 output[HASH_MAX_DIGEST_SIZE];
+               u8 vsum[HASH_MAX_DIGEST_SIZE];
 
-       if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
-               puts("HASH_MAX_DIGEST_SIZE exceeded\n");
-               return 1;
-       }
+               algo = find_hash_algo(algo_name);
+               if (!algo) {
+                       printf("Unknown hash algorithm '%s'\n", algo_name);
+                       return CMD_RET_USAGE;
+               }
+               argc -= 2;
+
+               if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
+                       puts("HASH_MAX_DIGEST_SIZE exceeded\n");
+                       return 1;
+               }
 
-       algo->hash_func_ws((const unsigned char *)addr, len, output,
-                          algo->chunk_size);
+               algo->hash_func_ws((const unsigned char *)addr, len, output,
+                                  algo->chunk_size);
 
-       /* Try to avoid code bloat when verify is not needed */
+               /* Try to avoid code bloat when verify is not needed */
 #ifdef CONFIG_HASH_VERIFY
-       if (flags & HASH_FLAG_VERIFY) {
+               if (flags & HASH_FLAG_VERIFY) {
 #else
-       if (0) {
+               if (0) {
 #endif
-               if (!argc)
-                       return CMD_RET_USAGE;
-               if (parse_verify_sum(algo, *argv, vsum,
+                       if (!argc)
+                               return CMD_RET_USAGE;
+                       if (parse_verify_sum(algo, *argv, vsum,
                                        flags & HASH_FLAG_ENV)) {
-                       printf("ERROR: %s does not contain a valid %s sum\n",
-                               *argv, algo->name);
-                       return 1;
-               }
-               if (memcmp(output, vsum, algo->digest_size) != 0) {
-                       int i;
+                               printf("ERROR: %s does not contain a valid "
+                                       "%s sum\n", *argv, algo->name);
+                               return 1;
+                       }
+                       if (memcmp(output, vsum, algo->digest_size) != 0) {
+                               int i;
 
+                               show_hash(algo, addr, len, output);
+                               printf(" != ");
+                               for (i = 0; i < algo->digest_size; i++)
+                                       printf("%02x", vsum[i]);
+                               puts(" ** ERROR **\n");
+                               return 1;
+                       }
+               } else {
                        show_hash(algo, addr, len, output);
-                       printf(" != ");
-                       for (i = 0; i < algo->digest_size; i++)
-                               printf("%02x", vsum[i]);
-                       puts(" ** ERROR **\n");
-                       return 1;
+                       printf("\n");
+
+                       if (argc) {
+                               store_result(algo, output, *argv,
+                                       flags & HASH_FLAG_ENV);
+                       }
                }
+
+       /* Horrible code size hack for boards that just want crc32 */
        } else {
-               show_hash(algo, addr, len, output);
-               printf("\n");
+               ulong crc;
+               ulong *ptr;
+
+               crc = crc32_wd(0, (const uchar *)addr, len, CHUNKSZ_CRC32);
+
+               printf("CRC32 for %08lx ... %08lx ==> %08lx\n",
+                               addr, addr + len - 1, crc);
 
-               if (argc) {
-                       store_result(algo, output, *argv,
-                               flags & HASH_FLAG_ENV);
+               if (argc > 3) {
+                       ptr = (ulong *)simple_strtoul(argv[3], NULL, 16);
+                       *ptr = crc;
                }
        }