nand/fileio: change prototype of nand_fileio_start()
[fw/openocd] / src / flash / nand / tcl.c
index 70584fff52c35b439da849b42fe78c709e79bff2..5e8b46e810be777d776d974b8ea1f7bb3ef2578c 100644 (file)
  *   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.             *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -27,8 +26,9 @@
 #include "core.h"
 #include "imp.h"
 #include "fileio.h"
+#include <target/target.h>
 
-// to be removed
+/* to be removed */
 extern struct nand_device *nand_devices;
 
 COMMAND_HANDLER(handle_nand_list_command)
@@ -36,14 +36,12 @@ COMMAND_HANDLER(handle_nand_list_command)
        struct nand_device *p;
        int i;
 
-       if (!nand_devices)
-       {
+       if (!nand_devices) {
                command_print(CMD_CTX, "no NAND flash devices configured");
                return ERROR_OK;
        }
 
-       for (p = nand_devices, i = 0; p; p = p->next, i++)
-       {
+       for (p = nand_devices, i = 0; p; p = p->next, i++) {
                if (p->device)
                        command_print(CMD_CTX, "#%i: %s (%s) "
                                "pagesize: %i, buswidth: %i,\n\t"
@@ -66,21 +64,21 @@ COMMAND_HANDLER(handle_nand_info_command)
        int last = -1;
 
        switch (CMD_ARGC) {
-       default:
-               return ERROR_COMMAND_SYNTAX_ERROR;
-       case 1:
-               first = 0;
-               last = INT32_MAX;
-               break;
-       case 2:
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], i);
-               first = last = i;
-               i = 0;
-               break;
-       case 3:
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first);
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last);
-               break;
+               default:
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               case 1:
+                       first = 0;
+                       last = INT32_MAX;
+                       break;
+               case 2:
+                       COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], i);
+                       first = last = i;
+                       i = 0;
+                       break;
+               case 3:
+                       COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first);
+                       COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last);
+                       break;
        }
 
        struct nand_device *p;
@@ -88,8 +86,7 @@ COMMAND_HANDLER(handle_nand_info_command)
        if (ERROR_OK != retval)
                return retval;
 
-       if (NULL == p->device)
-       {
+       if (NULL == p->device) {
                command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]);
                return ERROR_OK;
        }
@@ -100,11 +97,16 @@ COMMAND_HANDLER(handle_nand_info_command)
        if (last >= p->num_blocks)
                last = p->num_blocks - 1;
 
-       command_print(CMD_CTX, "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i",
-               i++, p->device->name, p->manufacturer->name, p->page_size, p->bus_width, p->erase_size);
+       command_print(CMD_CTX,
+               "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i",
+               i++,
+               p->device->name,
+               p->manufacturer->name,
+               p->page_size,
+               p->bus_width,
+               p->erase_size);
 
-       for (j = first; j <= last; j++)
-       {
+       for (j = first; j <= last; j++) {
                char *erase_state, *bad_state;
 
                if (p->blocks[j].is_erased == 0)
@@ -122,12 +124,12 @@ COMMAND_HANDLER(handle_nand_info_command)
                        bad_state = " (block condition unknown)";
 
                command_print(CMD_CTX,
-                             "\t#%i: 0x%8.8" PRIx32 " (%" PRId32 "kB) %s%s",
-                             j,
-                             p->blocks[j].offset,
-                             p->blocks[j].size / 1024,
-                             erase_state,
-                             bad_state);
+                       "\t#%i: 0x%8.8" PRIx32 " (%" PRId32 "kB) %s%s",
+                       j,
+                       p->blocks[j].offset,
+                       p->blocks[j].size / 1024,
+                       erase_state,
+                       bad_state);
        }
 
        return ERROR_OK;
@@ -136,19 +138,17 @@ COMMAND_HANDLER(handle_nand_info_command)
 COMMAND_HANDLER(handle_nand_probe_command)
 {
        if (CMD_ARGC != 1)
-       {
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        struct nand_device *p;
        int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
        if (ERROR_OK != retval)
                return retval;
 
-       if ((retval = nand_probe(p)) == ERROR_OK)
-       {
+       retval = nand_probe(p);
+       if (retval == ERROR_OK) {
                command_print(CMD_CTX, "NAND flash device '%s (%s)' found",
-                               p->device->name, p->manufacturer->name);
+                       p->device->name, p->manufacturer->name);
        }
 
        return retval;
@@ -157,11 +157,8 @@ COMMAND_HANDLER(handle_nand_probe_command)
 COMMAND_HANDLER(handle_nand_erase_command)
 {
        if (CMD_ARGC != 1 && CMD_ARGC != 3)
-       {
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       }
-
        struct nand_device *p;
        int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
        if (ERROR_OK != retval)
@@ -176,12 +173,12 @@ COMMAND_HANDLER(handle_nand_erase_command)
 
                COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], offset);
                if ((offset % p->erase_size) != 0 || offset >= size)
-                       return ERROR_INVALID_ARGUMENTS;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
 
                COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length);
                if ((length == 0) || (length % p->erase_size) != 0
-                               || (length + offset) > size)
-                       return ERROR_INVALID_ARGUMENTS;
+                   || (length + offset) > size)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
 
                offset /= p->erase_size;
                length /= p->erase_size;
@@ -191,12 +188,11 @@ COMMAND_HANDLER(handle_nand_erase_command)
        }
 
        retval = nand_erase(p, offset, offset + length - 1);
-       if (retval == ERROR_OK)
-       {
+       if (retval == ERROR_OK) {
                command_print(CMD_CTX, "erased blocks %lu to %lu "
-                               "on NAND flash device #%s '%s'",
-                               offset, offset + length,
-                               CMD_ARGV[0], p->device->name);
+                       "on NAND flash device #%s '%s'",
+                       offset, offset + length - 1,
+                       CMD_ARGV[0], p->device->name);
        }
 
        return retval;
@@ -208,29 +204,25 @@ COMMAND_HANDLER(handle_nand_check_bad_blocks_command)
        int last = -1;
 
        if ((CMD_ARGC < 1) || (CMD_ARGC > 3) || (CMD_ARGC == 2))
-       {
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       }
-
        struct nand_device *p;
        int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
        if (ERROR_OK != retval)
                return retval;
 
-       if (CMD_ARGC == 3)
-       {
+       if (CMD_ARGC == 3) {
                unsigned long offset;
                unsigned long length;
 
                COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], offset);
                if (offset % p->erase_size)
-                       return ERROR_INVALID_ARGUMENTS;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
                offset /= p->erase_size;
 
                COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length);
                if (length % p->erase_size)
-                       return ERROR_INVALID_ARGUMENTS;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
 
                length -= 1;
                length /= p->erase_size;
@@ -240,10 +232,9 @@ COMMAND_HANDLER(handle_nand_check_bad_blocks_command)
        }
 
        retval = nand_build_bbt(p, first, last);
-       if (retval == ERROR_OK)
-       {
+       if (retval == ERROR_OK) {
                command_print(CMD_CTX, "checked NAND flash device for bad blocks, "
-                               "use \"nand info\" command to list blocks");
+                       "use \"nand info\" command to list blocks");
        }
 
        return retval;
@@ -259,34 +250,32 @@ COMMAND_HANDLER(handle_nand_write_command)
                return retval;
 
        uint32_t total_bytes = s.size;
-       while (s.size > 0)
-       {
+       while (s.size > 0) {
                int bytes_read = nand_fileio_read(nand, &s);
-               if (bytes_read <= 0)
-               {
+               if (bytes_read <= 0) {
                        command_print(CMD_CTX, "error while reading file");
-                       return nand_fileio_cleanup(&s);
+                       nand_fileio_cleanup(&s);
+                       return ERROR_FAIL;
                }
                s.size -= bytes_read;
 
                retval = nand_write_page(nand, s.address / nand->page_size,
                                s.page, s.page_size, s.oob, s.oob_size);
-               if (ERROR_OK != retval)
-               {
+               if (ERROR_OK != retval) {
                        command_print(CMD_CTX, "failed writing file %s "
                                "to NAND flash %s at offset 0x%8.8" PRIx32,
                                CMD_ARGV[1], CMD_ARGV[0], s.address);
-                       return nand_fileio_cleanup(&s);
+                       nand_fileio_cleanup(&s);
+                       return retval;
                }
                s.address += s.page_size;
        }
 
-       if (nand_fileio_finish(&s))
-       {
+       if (nand_fileio_finish(&s) == ERROR_OK) {
                command_print(CMD_CTX, "wrote file %s to NAND flash %s up to "
-                               "offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
-                               CMD_ARGV[1], CMD_ARGV[0], s.address, duration_elapsed(&s.bench),
-                               duration_kbps(&s.bench, total_bytes));
+                       "offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
+                       CMD_ARGV[1], CMD_ARGV[0], s.address, duration_elapsed(&s.bench),
+                       duration_kbps(&s.bench, total_bytes));
        }
        return ERROR_OK;
 }
@@ -305,16 +294,14 @@ COMMAND_HANDLER(handle_nand_verify_command)
        dev.address = file.address;
        dev.size = file.size;
        dev.oob_format = file.oob_format;
-       retval = nand_fileio_start(CMD_CTX, nand, NULL, FILEIO_NONE, &dev);
+       retval = nand_fileio_start(CMD, nand, NULL, FILEIO_NONE, &dev);
        if (ERROR_OK != retval)
                return retval;
 
-       while (file.size > 0)
-       {
+       while (file.size > 0) {
                retval = nand_read_page(nand, dev.address / dev.page_size,
                                dev.page, dev.page_size, dev.oob, dev.oob_size);
-               if (ERROR_OK != retval)
-               {
+               if (ERROR_OK != retval) {
                        command_print(CMD_CTX, "reading NAND flash page failed");
                        nand_fileio_cleanup(&dev);
                        nand_fileio_cleanup(&file);
@@ -322,8 +309,7 @@ COMMAND_HANDLER(handle_nand_verify_command)
                }
 
                int bytes_read = nand_fileio_read(nand, &file);
-               if (bytes_read <= 0)
-               {
+               if (bytes_read <= 0) {
                        command_print(CMD_CTX, "error while reading file");
                        nand_fileio_cleanup(&dev);
                        nand_fileio_cleanup(&file);
@@ -331,10 +317,9 @@ COMMAND_HANDLER(handle_nand_verify_command)
                }
 
                if ((dev.page && memcmp(dev.page, file.page, dev.page_size)) ||
-                   (dev.oob && memcmp(dev.oob, file.oob, dev.oob_size)) )
-               {
+                               (dev.oob && memcmp(dev.oob, file.oob, dev.oob_size))) {
                        command_print(CMD_CTX, "NAND flash contents differ "
-                                               "at 0x%8.8" PRIx32, dev.address);
+                               "at 0x%8.8" PRIx32, dev.address);
                        nand_fileio_cleanup(&dev);
                        nand_fileio_cleanup(&file);
                        return ERROR_FAIL;
@@ -344,12 +329,11 @@ COMMAND_HANDLER(handle_nand_verify_command)
                dev.address += nand->page_size;
        }
 
-       if (nand_fileio_finish(&file) == ERROR_OK)
-       {
+       if (nand_fileio_finish(&file) == ERROR_OK) {
                command_print(CMD_CTX, "verified file %s in NAND flash %s "
-                               "up to offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
-                               CMD_ARGV[1], CMD_ARGV[0], dev.address, duration_elapsed(&file.bench),
-                               duration_kbps(&file.bench, dev.size));
+                       "up to offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
+                       CMD_ARGV[1], CMD_ARGV[0], dev.address, duration_elapsed(&file.bench),
+                       duration_kbps(&file.bench, dev.size));
        }
 
        return nand_fileio_cleanup(&dev);
@@ -357,7 +341,7 @@ COMMAND_HANDLER(handle_nand_verify_command)
 
 COMMAND_HANDLER(handle_nand_dump_command)
 {
-       int filesize;
+       size_t filesize;
        struct nand_device *nand = NULL;
        struct nand_fileio_state s;
        int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,
@@ -365,37 +349,34 @@ COMMAND_HANDLER(handle_nand_dump_command)
        if (ERROR_OK != retval)
                return retval;
 
-       while (s.size > 0)
-       {
+       while (s.size > 0) {
                size_t size_written;
                retval = nand_read_page(nand, s.address / nand->page_size,
                                s.page, s.page_size, s.oob, s.oob_size);
-               if (ERROR_OK != retval)
-               {
+               if (ERROR_OK != retval) {
                        command_print(CMD_CTX, "reading NAND flash page failed");
                        nand_fileio_cleanup(&s);
                        return retval;
                }
 
                if (NULL != s.page)
-                       fileio_write(&s.fileio, s.page_size, s.page, &size_written);
+                       fileio_write(s.fileio, s.page_size, s.page, &size_written);
 
                if (NULL != s.oob)
-                       fileio_write(&s.fileio, s.oob_size, s.oob, &size_written);
+                       fileio_write(s.fileio, s.oob_size, s.oob, &size_written);
 
                s.size -= nand->page_size;
                s.address += nand->page_size;
        }
 
-       retval = fileio_size(&s.fileio, &filesize);
+       retval = fileio_size(s.fileio, &filesize);
        if (retval != ERROR_OK)
                return retval;
 
-       if (nand_fileio_finish(&s) == ERROR_OK)
-       {
-               command_print(CMD_CTX, "dumped %ld bytes in %fs (%0.3f KiB/s)",
-                               (long)filesize, duration_elapsed(&s.bench),
-                               duration_kbps(&s.bench, filesize));
+       if (nand_fileio_finish(&s) == ERROR_OK) {
+               command_print(CMD_CTX, "dumped %zu bytes in %fs (%0.3f KiB/s)",
+                       filesize, duration_elapsed(&s.bench),
+                       duration_kbps(&s.bench, filesize));
        }
        return ERROR_OK;
 }
@@ -403,17 +384,14 @@ COMMAND_HANDLER(handle_nand_dump_command)
 COMMAND_HANDLER(handle_nand_raw_access_command)
 {
        if ((CMD_ARGC < 1) || (CMD_ARGC > 2))
-       {
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        struct nand_device *p;
        int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
        if (ERROR_OK != retval)
                return retval;
 
-       if (NULL == p->device)
-       {
+       if (NULL == p->device) {
                command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]);
                return ERROR_OK;
        }
@@ -433,6 +411,7 @@ static const struct command_registration nand_exec_command_handlers[] = {
                .handler = handle_nand_list_command,
                .mode = COMMAND_EXEC,
                .help = "list configured NAND flash devices",
+               .usage = "",
        },
        {
                .name = "info",
@@ -509,9 +488,8 @@ COMMAND_HANDLER(handle_nand_init_command)
        if (CMD_ARGC != 0)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       static bool nand_initialized = false;
-       if (nand_initialized)
-       {
+       static bool nand_initialized;
+       if (nand_initialized) {
                LOG_INFO("'nand init' has already been called");
                return ERROR_OK;
        }
@@ -523,7 +501,7 @@ COMMAND_HANDLER(handle_nand_init_command)
 
 static int nand_list_walker(struct nand_flash_controller *c, void *x)
 {
-       struct command_context *cmd_ctx = (struct command_context *)x;
+       struct command_context *cmd_ctx = x;
        command_print(cmd_ctx, "  %s", c->name);
        return ERROR_OK;
 }
@@ -535,18 +513,34 @@ COMMAND_HANDLER(handle_nand_list_drivers)
 }
 
 static COMMAND_HELPER(create_nand_device, const char *bank_name,
-               struct nand_flash_controller *controller)
+       struct nand_flash_controller *controller)
 {
-       if (NULL != controller->commands)
-       {
-               int retval = register_commands(CMD_CTX, NULL,
+       struct nand_device *c;
+       struct target *target;
+       int retval;
+
+       if (CMD_ARGC < 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       target = get_target(CMD_ARGV[1]);
+       if (!target) {
+               LOG_ERROR("invalid target %s", CMD_ARGV[1]);
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+       }
+
+       if (NULL != controller->commands) {
+               retval = register_commands(CMD_CTX, NULL,
                                controller->commands);
                if (ERROR_OK != retval)
                        return retval;
        }
-       struct nand_device *c = malloc(sizeof(struct nand_device));
+       c = malloc(sizeof(struct nand_device));
+       if (c == NULL) {
+               LOG_ERROR("End of memory");
+               return ERROR_FAIL;
+       }
 
        c->name = strdup(bank_name);
+       c->target = target;
        c->controller = controller;
        c->controller_priv = NULL;
        c->manufacturer = NULL;
@@ -554,17 +548,21 @@ static COMMAND_HELPER(create_nand_device, const char *bank_name,
        c->bus_width = 0;
        c->address_cycles = 0;
        c->page_size = 0;
-       c->use_raw = 0;
+       c->use_raw = false;
        c->next = NULL;
 
-       int retval = CALL_COMMAND_HANDLER(controller->nand_device_command, c);
-       if (ERROR_OK != retval)
-       {
-               LOG_ERROR("'%s' driver rejected nand flash", controller->name);
+       retval = CALL_COMMAND_HANDLER(controller->nand_device_command, c);
+       if (ERROR_OK != retval) {
+               LOG_ERROR("'%s' driver rejected nand flash. Usage: %s",
+                       controller->name,
+                       controller->usage);
                free(c);
-               return ERROR_OK;
+               return retval;
        }
 
+       if (controller->usage == NULL)
+               LOG_DEBUG("'%s' driver usage field missing", controller->name);
+
        nand_device_add(c);
 
        return ERROR_OK;
@@ -573,20 +571,16 @@ static COMMAND_HELPER(create_nand_device, const char *bank_name,
 COMMAND_HANDLER(handle_nand_device_command)
 {
        if (CMD_ARGC < 2)
-       {
-               LOG_ERROR("incomplete nand device configuration");
-               return ERROR_FLASH_BANK_INVALID;
-       }
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       // save name and increment (for compatibility) with drivers
+       /* save name and increment (for compatibility) with drivers */
        const char *bank_name = *CMD_ARGV++;
        CMD_ARGC--;
 
        const char *driver_name = CMD_ARGV[0];
        struct nand_flash_controller *controller;
        controller = nand_driver_find_by_name(CMD_ARGV[0]);
-       if (NULL == controller)
-       {
+       if (NULL == controller) {
                LOG_ERROR("No valid NAND flash driver found (%s)", driver_name);
                return CALL_COMMAND_HANDLER(handle_nand_list_drivers);
        }
@@ -606,20 +600,24 @@ static const struct command_registration nand_config_command_handlers[] = {
                .handler = &handle_nand_list_drivers,
                .mode = COMMAND_ANY,
                .help = "lists available NAND drivers",
+               .usage = ""
        },
        {
                .name = "init",
                .mode = COMMAND_CONFIG,
                .handler = &handle_nand_init_command,
                .help = "initialize NAND devices",
+               .usage = ""
        },
        COMMAND_REGISTRATION_DONE
 };
+
 static const struct command_registration nand_command_handlers[] = {
        {
                .name = "nand",
                .mode = COMMAND_ANY,
                .help = "NAND flash command group",
+               .usage = "",
                .chain = nand_config_command_handlers,
        },
        COMMAND_REGISTRATION_DONE
@@ -629,5 +627,3 @@ int nand_register_commands(struct command_context *cmd_ctx)
 {
        return register_commands(cmd_ctx, NULL, nand_command_handlers);
 }
-
-