#include "core.h"
#include "imp.h"
#include "fileio.h"
+#include <target/target.h>
// to be removed
extern struct nand_device *nand_devices;
if ((retval = nand_probe(p)) == ERROR_OK)
{
- command_print(CMD_CTX, "NAND flash device '%s' found", p->device->name);
- }
- else if (retval == ERROR_NAND_OPERATION_FAILED)
- {
- command_print(CMD_CTX, "probing failed for NAND flash device");
- }
- else
- {
- command_print(CMD_CTX, "unknown error when probing NAND flash device");
+ command_print(CMD_CTX, "NAND flash device '%s (%s)' found",
+ p->device->name, p->manufacturer->name);
}
- return ERROR_OK;
+ return retval;
}
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;
+ return ERROR_COMMAND_SYNTAX_ERROR;
offset /= p->erase_size;
length /= p->erase_size;
{
command_print(CMD_CTX, "erased blocks %lu to %lu "
"on NAND flash device #%s '%s'",
- offset, offset + length,
+ offset, offset + length - 1,
CMD_ARGV[0], p->device->name);
}
- else if (retval == ERROR_NAND_OPERATION_FAILED)
- {
- command_print(CMD_CTX, "erase failed");
- }
- else
- {
- command_print(CMD_CTX, "unknown error when erasing NAND flash device");
- }
- return ERROR_OK;
+ return retval;
}
COMMAND_HANDLER(handle_nand_check_bad_blocks_command)
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;
command_print(CMD_CTX, "checked NAND flash device for bad blocks, "
"use \"nand info\" command to list blocks");
}
- else if (retval == ERROR_NAND_OPERATION_FAILED)
- {
- command_print(CMD_CTX, "error when checking for bad blocks on "
- "NAND flash device");
- }
- else
- {
- command_print(CMD_CTX, "unknown error when checking for bad "
- "blocks on NAND flash device");
- }
- return ERROR_OK;
+ return retval;
}
COMMAND_HANDLER(handle_nand_write_command)
if (nand_fileio_finish(&s))
{
command_print(CMD_CTX, "wrote file %s to NAND flash %s up to "
- "offset 0x%8.8" PRIx32 " in %fs (%0.3f kb/s)",
+ "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));
}
while (file.size > 0)
{
- int retval = nand_read_page(nand, dev.address / dev.page_size,
+ retval = nand_read_page(nand, dev.address / dev.page_size,
dev.page, dev.page_size, dev.oob, dev.oob_size);
if (ERROR_OK != retval)
{
command_print(CMD_CTX, "reading NAND flash page failed");
nand_fileio_cleanup(&dev);
- return nand_fileio_cleanup(&file);
+ nand_fileio_cleanup(&file);
+ return retval;
}
int bytes_read = nand_fileio_read(nand, &file);
{
command_print(CMD_CTX, "error while reading file");
nand_fileio_cleanup(&dev);
- return nand_fileio_cleanup(&file);
+ nand_fileio_cleanup(&file);
+ return ERROR_FAIL;
}
if ((dev.page && memcmp(dev.page, file.page, dev.page_size)) ||
command_print(CMD_CTX, "NAND flash contents differ "
"at 0x%8.8" PRIx32, dev.address);
nand_fileio_cleanup(&dev);
- return nand_fileio_cleanup(&file);
+ nand_fileio_cleanup(&file);
+ return ERROR_FAIL;
}
file.size -= bytes_read;
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 kb/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));
}
COMMAND_HANDLER(handle_nand_dump_command)
{
+ int filesize;
struct nand_device *nand = NULL;
struct nand_fileio_state s;
int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,
while (s.size > 0)
{
size_t size_written;
- int retval = nand_read_page(nand, s.address / nand->page_size,
+ retval = nand_read_page(nand, s.address / nand->page_size,
s.page, s.page_size, s.oob, s.oob_size);
if (ERROR_OK != retval)
{
command_print(CMD_CTX, "reading NAND flash page failed");
- return nand_fileio_cleanup(&s);
+ nand_fileio_cleanup(&s);
+ return retval;
}
if (NULL != s.page)
s.address += nand->page_size;
}
+ retval = fileio_size(&s.fileio, &filesize);
+ if (retval != ERROR_OK)
+ return retval;
+
if (nand_fileio_finish(&s) == ERROR_OK)
{
- command_print(CMD_CTX, "dumped %zu bytes in %fs (%0.3f kb/s)",
- s.fileio.size, duration_elapsed(&s.bench),
- duration_kbps(&s.bench, s.fileio.size));
+ command_print(CMD_CTX, "dumped %ld bytes in %fs (%0.3f KiB/s)",
+ (long)filesize, duration_elapsed(&s.bench),
+ duration_kbps(&s.bench, filesize));
}
return ERROR_OK;
}
static const struct command_registration nand_exec_command_handlers[] = {
{
.name = "list",
- .handler = &handle_nand_list_command,
+ .handler = handle_nand_list_command,
.mode = COMMAND_EXEC,
.help = "list configured NAND flash devices",
},
{
.name = "info",
- .handler = &handle_nand_info_command,
+ .handler = handle_nand_info_command,
.mode = COMMAND_EXEC,
- .usage = "<bank>",
- .help = "print info about a NAND flash device",
+ .usage = "[banknum | first_bank_num last_bank_num]",
+ .help = "print info about one or more NAND flash devices",
},
{
.name = "probe",
- .handler = &handle_nand_probe_command,
+ .handler = handle_nand_probe_command,
.mode = COMMAND_EXEC,
- .usage = "<bank>",
- .help = "identify NAND flash device <num>",
-
+ .usage = "bank_id",
+ .help = "identify NAND flash device",
},
{
.name = "check_bad_blocks",
- .handler = &handle_nand_check_bad_blocks_command,
+ .handler = handle_nand_check_bad_blocks_command,
.mode = COMMAND_EXEC,
- .usage = "<bank> [<offset> <length>]",
- .help = "check NAND flash device <num> for bad blocks",
+ .usage = "bank_id [offset length]",
+ .help = "check all or part of NAND flash device for bad blocks",
},
{
.name = "erase",
- .handler = &handle_nand_erase_command,
+ .handler = handle_nand_erase_command,
.mode = COMMAND_EXEC,
- .usage = "<bank> [<offset> <length>]",
- .help = "erase blocks on NAND flash device",
+ .usage = "bank_id [offset length]",
+ .help = "erase all or subset of blocks on NAND flash device",
},
{
.name = "dump",
- .handler = &handle_nand_dump_command,
+ .handler = handle_nand_dump_command,
.mode = COMMAND_EXEC,
- .usage = "<bank> <filename> <offset> <length> "
- "[oob_raw | oob_only]",
+ .usage = "bank_id filename offset length "
+ "['oob_raw'|'oob_only']",
.help = "dump from NAND flash device",
},
{
.name = "verify",
- .handler = &handle_nand_verify_command,
+ .handler = handle_nand_verify_command,
.mode = COMMAND_EXEC,
- .usage = "<bank> <filename> <offset> "
- "[oob_raw | oob_only | oob_softecc | oob_softecc_kw]",
+ .usage = "bank_id filename offset "
+ "['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']",
.help = "verify NAND flash device",
},
{
.name = "write",
- .handler = &handle_nand_write_command,
+ .handler = handle_nand_write_command,
.mode = COMMAND_EXEC,
- .usage = "<bank> <filename> <offset> "
- "[oob_raw | oob_only | oob_softecc | oob_softecc_kw]",
+ .usage = "bank_id filename offset "
+ "['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']",
.help = "write to NAND flash device",
},
{
.name = "raw_access",
- .handler = &handle_nand_raw_access_command,
+ .handler = handle_nand_raw_access_command,
.mode = COMMAND_EXEC,
- .usage = "<num> ['enable'|'disable']",
+ .usage = "bank_id ['enable'|'disable']",
.help = "raw access to NAND flash device",
},
COMMAND_REGISTRATION_DONE
};
-int nand_init(struct command_context *cmd_ctx)
+static int nand_init(struct command_context *cmd_ctx)
{
if (!nand_devices)
return ERROR_OK;
LOG_DEBUG("Initializing NAND devices...");
return nand_init(CMD_CTX);
}
-int nand_list_walker(struct nand_flash_controller *c, void *x)
+
+static int nand_list_walker(struct nand_flash_controller *c, void *x)
{
struct command_context *cmd_ctx = (struct command_context *)x;
command_print(cmd_ctx, " %s", c->name);
return ERROR_OK;
}
+
COMMAND_HANDLER(handle_nand_list_drivers)
{
command_print(CMD_CTX, "Available NAND flash controller drivers:");
static COMMAND_HELPER(create_nand_device, const char *bank_name,
struct nand_flash_controller *controller)
{
+ 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)
{
- int retval = register_commands(CMD_CTX, NULL,
+ 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;
c->use_raw = 0;
c->next = NULL;
- int retval = CALL_COMMAND_HANDLER(controller->nand_device_command, c);
+ retval = CALL_COMMAND_HANDLER(controller->nand_device_command, c);
if (ERROR_OK != retval)
{
- LOG_ERROR("'%s' driver rejected nand flash", controller->name);
+ 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;
}
COMMAND_HANDLER(handle_nand_device_command)
{
- if (CMD_ARGC < 1)
+ 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
.handler = &handle_nand_device_command,
.mode = COMMAND_CONFIG,
.help = "defines a new NAND bank",
+ .usage = "bank_id driver target [driver_options ...]",
},
{
.name = "drivers",
.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
};
.name = "nand",
.mode = COMMAND_ANY,
.help = "NAND flash command group",
+ .usage = "",
.chain = nand_config_command_handlers,
},
COMMAND_REGISTRATION_DONE