]> git.sur5r.net Git - openocd/blobdiff - src/flash/nand.c
Improve str7x config command argument parsing.
[openocd] / src / flash / nand.c
index 87eb976a79b760e88a0e33c9e479ba0a777e8b30..7fb7c99e7ae8e9dd42e661d922f2ad297d8c9783 100644 (file)
 #include "time_support.h"
 #include "fileio.h"
 
-#include <inttypes.h>
-
-
 static int handle_nand_list_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_nand_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_nand_check_bad_blocks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-static int handle_nand_copy_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 
 static int handle_nand_raw_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 
-static int nand_read_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);
-//static int nand_read_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size);
+static int nand_read_page(struct nand_device_s *device, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
+//static int nand_read_plain(struct nand_device_s *device, uint32_t address, uint8_t *data, uint32_t data_size);
 
-static int nand_write_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);
+static int nand_write_page(struct nand_device_s *device, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
 
 /* NAND flash controller
  */
+extern nand_flash_controller_t davinci_nand_controller;
 extern nand_flash_controller_t lpc3180_nand_controller;
 extern nand_flash_controller_t orion_nand_controller;
 extern nand_flash_controller_t s3c2410_nand_controller;
 extern nand_flash_controller_t s3c2412_nand_controller;
 extern nand_flash_controller_t s3c2440_nand_controller;
 extern nand_flash_controller_t s3c2443_nand_controller;
+extern nand_flash_controller_t imx31_nand_flash_controller;
 
 /* extern nand_flash_controller_t boundary_scan_nand_controller; */
 
 static nand_flash_controller_t *nand_flash_controllers[] =
 {
+       &davinci_nand_controller,
        &lpc3180_nand_controller,
        &orion_nand_controller,
        &s3c2410_nand_controller,
        &s3c2412_nand_controller,
        &s3c2440_nand_controller,
        &s3c2443_nand_controller,
+       &imx31_nand_flash_controller,
 /*     &boundary_scan_nand_controller, */
        NULL
 };
@@ -86,6 +86,7 @@ static command_t *nand_cmd;
  */
 static nand_info_t nand_flash_ids[] =
 {
+       /* start "museum" IDs */
        {"NAND 1MiB 5V 8-bit",          0x6e, 256, 1, 0x1000, 0},
        {"NAND 2MiB 5V 8-bit",          0x64, 256, 2, 0x1000, 0},
        {"NAND 4MiB 5V 8-bit",          0x6b, 512, 4, 0x2000, 0},
@@ -101,6 +102,7 @@ static nand_info_t nand_flash_ids[] =
        {"NAND 8MiB 3,3V 8-bit",        0xe6, 512, 8, 0x2000, 0},
        {"NAND 8MiB 1,8V 16-bit",       0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
        {"NAND 8MiB 3,3V 16-bit",       0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
+       /* end "museum" IDs */
 
        {"NAND 16MiB 1,8V 8-bit",       0x33, 512, 16, 0x4000, 0},
        {"NAND 16MiB 3,3V 8-bit",       0x73, 512, 16, 0x4000, 0},
@@ -172,6 +174,7 @@ static nand_manufacturer_t nand_manuf_ids[] =
        {NAND_MFR_RENESAS, "Renesas"},
        {NAND_MFR_STMICRO, "ST Micro"},
        {NAND_MFR_HYNIX, "Hynix"},
+       {NAND_MFR_MICRON, "Micron"},
        {0x0, NULL},
 };
 
@@ -305,15 +308,15 @@ int nand_init(struct command_context_s *cmd_ctx)
                register_command(cmd_ctx, nand_cmd, "probe", handle_nand_probe_command, COMMAND_EXEC,
                                                 "identify NAND flash device <num>");
                register_command(cmd_ctx, nand_cmd, "check_bad_blocks", handle_nand_check_bad_blocks_command, COMMAND_EXEC,
-                                                "check NAND flash device <num> for bad blocks [<first> <last>]");
-               register_command(cmd_ctx, nand_cmd, "erase", handle_nand_erase_command, COMMAND_EXEC,
-                                                "erase blocks on NAND flash device <num> <first> <last>");
-               register_command(cmd_ctx, nand_cmd, "copy", handle_nand_copy_command, COMMAND_EXEC,
-                                                "copy from NAND flash device <num> <offset> <length> <ram-address>");
+                                                "check NAND flash device <num> for bad blocks [<offset> <length>]");
+               register_command(cmd_ctx, nand_cmd, "erase",
+                               handle_nand_erase_command, COMMAND_EXEC,
+                               "erase blocks on NAND flash device <num> [<offset> <length>]");
                register_command(cmd_ctx, nand_cmd, "dump", handle_nand_dump_command, COMMAND_EXEC,
-                                                "dump from NAND flash device <num> <filename> <offset> <size> [options]");
+                                                "dump from NAND flash device <num> <filename> "
+                                                "<offset> <length> [oob_raw | oob_only]");
                register_command(cmd_ctx, nand_cmd, "write", handle_nand_write_command, COMMAND_EXEC,
-                                                "write to NAND flash device <num> <filename> <offset> [oob_raw|oob_only|oob_softecc]");
+                                                "write to NAND flash device <num> <filename> <offset> [oob_raw | oob_only | oob_softecc | oob_softecc_kw]");
                register_command(cmd_ctx, nand_cmd, "raw_access", handle_nand_raw_access_command, COMMAND_EXEC,
                                                 "raw access to NAND flash device <num> ['enable'|'disable']");
        }
@@ -337,11 +340,24 @@ nand_device_t *get_nand_device_by_num(int num)
        return NULL;
 }
 
+int nand_command_get_device_by_num(struct command_context_s *cmd_ctx,
+               char *str, nand_device_t **device)
+{
+       unsigned num;
+       COMMAND_PARSE_NUMBER(uint, str, num);
+       *device = get_nand_device_by_num(num);
+       if (!*device) {
+               command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", str);
+               return ERROR_INVALID_ARGUMENTS;
+       }
+       return ERROR_OK;
+}
+
 static int nand_build_bbt(struct nand_device_s *device, int first, int last)
 {
-       u32 page = 0x0;
+       uint32_t page = 0x0;
        int i;
-       u8 oob[6];
+       uint8_t oob[6];
 
        if ((first < 0) || (first >= device->num_blocks))
                first = 0;
@@ -357,7 +373,7 @@ static int nand_build_bbt(struct nand_device_s *device, int first, int last)
                        || (((device->page_size == 512) && (oob[5] != 0xff)) ||
                                ((device->page_size == 2048) && (oob[0] != 0xff))))
                {
-                       LOG_WARNING("invalid block: %i", i);
+                       LOG_WARNING("bad block: %i", i);
                        device->blocks[i].is_bad = 1;
                }
                else
@@ -371,7 +387,7 @@ static int nand_build_bbt(struct nand_device_s *device, int first, int last)
        return ERROR_OK;
 }
 
-int nand_read_status(struct nand_device_s *device, u8 *status)
+int nand_read_status(struct nand_device_s *device, uint8_t *status)
 {
        if (!device->device)
                return ERROR_NAND_DEVICE_NOT_PROBED;
@@ -384,7 +400,7 @@ int nand_read_status(struct nand_device_s *device, u8 *status)
        /* read status */
        if (device->device->options & NAND_BUSWIDTH_16)
        {
-               u16 data;
+               uint16_t data;
                device->controller->read_data(device, &data);
                *status = data & 0xff;
        }
@@ -398,12 +414,12 @@ int nand_read_status(struct nand_device_s *device, u8 *status)
 
 static int nand_poll_ready(struct nand_device_s *device, int timeout)
 {
-       u8 status;
+       uint8_t status;
 
        device->controller->command(device, NAND_CMD_STATUS);
        do {
                if (device->device->options & NAND_BUSWIDTH_16) {
-                       u16 data;
+                       uint16_t data;
                        device->controller->read_data(device, &data);
                        status = data & 0xff;
                } else {
@@ -419,8 +435,8 @@ static int nand_poll_ready(struct nand_device_s *device, int timeout)
 
 int nand_probe(struct nand_device_s *device)
 {
-       u8 manufacturer_id, device_id;
-       u8 id_buff[6];
+       uint8_t manufacturer_id, device_id;
+       uint8_t id_buff[6];
        int retval;
        int i;
 
@@ -464,7 +480,7 @@ int nand_probe(struct nand_device_s *device)
        }
        else
        {
-               u16 data_buf;
+               uint16_t data_buf;
                device->controller->read_data(device, &data_buf);
                manufacturer_id = data_buf & 0xff;
                device->controller->read_data(device, &data_buf);
@@ -518,13 +534,13 @@ int nand_probe(struct nand_device_s *device)
        {
                if (device->bus_width == 8)
                {
-                       device->controller->read_data(device, id_buff+3);
-                       device->controller->read_data(device, id_buff+4);
-                       device->controller->read_data(device, id_buff+5);
+                       device->controller->read_data(device, id_buff + 3);
+                       device->controller->read_data(device, id_buff + 4);
+                       device->controller->read_data(device, id_buff + 5);
                }
                else
                {
-                       u16 data_buf;
+                       uint16_t data_buf;
 
                        device->controller->read_data(device, &data_buf);
                        id_buff[3] = data_buf;
@@ -635,11 +651,11 @@ int nand_probe(struct nand_device_s *device)
        return ERROR_OK;
 }
 
-int nand_erase(struct nand_device_s *device, int first_block, int last_block)
+static int nand_erase(struct nand_device_s *device, int first_block, int last_block)
 {
        int i;
-       u32 page;
-       u8 status;
+       uint32_t page;
+       uint8_t status;
        int retval;
 
        if (!device->device)
@@ -710,8 +726,11 @@ int nand_erase(struct nand_device_s *device, int first_block, int last_block)
 
                if (status & 0x1)
                {
-                       LOG_ERROR("erase operation didn't pass, status: 0x%2.2x", status);
-                       return ERROR_NAND_OPERATION_FAILED;
+                       LOG_ERROR("didn't erase %sblock %d; status: 0x%2.2x",
+                                       (device->blocks[i].is_bad == 1)
+                                               ? "bad " : "",
+                                       i, status);
+                       /* continue; other blocks might still be erasable */
                }
 
                device->blocks[i].is_erased = 1;
@@ -721,9 +740,9 @@ int nand_erase(struct nand_device_s *device, int first_block, int last_block)
 }
 
 #if 0
-static int nand_read_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size)
+static int nand_read_plain(struct nand_device_s *device, uint32_t address, uint8_t *data, uint32_t data_size)
 {
-       u8 *page;
+       uint8_t *page;
 
        if (!device->device)
                return ERROR_NAND_DEVICE_NOT_PROBED;
@@ -736,10 +755,10 @@ static int nand_read_plain(struct nand_device_s *device, u32 address, u8 *data,
 
        page = malloc(device->page_size);
 
-       while (data_size > 0 )
+       while (data_size > 0)
        {
-               u32 thisrun_size = (data_size > device->page_size) ? device->page_size : data_size;
-               u32 page_address;
+               uint32_t thisrun_size = (data_size > device->page_size) ? device->page_size : data_size;
+               uint32_t page_address;
 
 
                page_address = address / device->page_size;
@@ -758,9 +777,9 @@ static int nand_read_plain(struct nand_device_s *device, u32 address, u8 *data,
        return ERROR_OK;
 }
 
-static int nand_write_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size)
+static int nand_write_plain(struct nand_device_s *device, uint32_t address, uint8_t *data, uint32_t data_size)
 {
-       u8 *page;
+       uint8_t *page;
 
        if (!device->device)
                return ERROR_NAND_DEVICE_NOT_PROBED;
@@ -773,10 +792,10 @@ static int nand_write_plain(struct nand_device_s *device, u32 address, u8 *data,
 
        page = malloc(device->page_size);
 
-       while (data_size > 0 )
+       while (data_size > 0)
        {
-               u32 thisrun_size = (data_size > device->page_size) ? device->page_size : data_size;
-               u32 page_address;
+               uint32_t thisrun_size = (data_size > device->page_size) ? device->page_size : data_size;
+               uint32_t page_address;
 
                memset(page, 0xff, device->page_size);
                memcpy(page, data, thisrun_size);
@@ -796,9 +815,9 @@ static int nand_write_plain(struct nand_device_s *device, u32 address, u8 *data,
 }
 #endif
 
-int nand_write_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)
+int nand_write_page(struct nand_device_s *device, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
-       u32 block;
+       uint32_t block;
 
        if (!device->device)
                return ERROR_NAND_DEVICE_NOT_PROBED;
@@ -813,7 +832,7 @@ int nand_write_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_s
                return device->controller->write_page(device, page, data, data_size, oob, oob_size);
 }
 
-static int nand_read_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)
+static int nand_read_page(struct nand_device_s *device, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
        if (!device->device)
                return ERROR_NAND_DEVICE_NOT_PROBED;
@@ -824,9 +843,9 @@ static int nand_read_page(struct nand_device_s *device, u32 page, u8 *data, u32
                return device->controller->read_page(device, page, data, data_size, oob, oob_size);
 }
 
-int nand_read_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)
+int nand_read_page_raw(struct nand_device_s *device, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
-       u32 i;
+       uint32_t i;
 
        if (!device->device)
                return ERROR_NAND_DEVICE_NOT_PROBED;
@@ -938,11 +957,11 @@ int nand_read_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 dat
        return ERROR_OK;
 }
 
-int nand_write_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)
+int nand_write_page_raw(struct nand_device_s *device, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
-       u32 i;
+       uint32_t i;
        int retval;
-       u8 status;
+       uint8_t status;
 
        if (!device->device)
                return ERROR_NAND_DEVICE_NOT_PROBED;
@@ -996,7 +1015,7 @@ int nand_write_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 da
                        {
                                if (device->device->options & NAND_BUSWIDTH_16)
                                {
-                                       u16 data_buf = le_to_h_u16(data);
+                                       uint16_t data_buf = le_to_h_u16(data);
                                        device->controller->write_data(device, data_buf);
                                        data += 2;
                                        i += 2;
@@ -1021,7 +1040,7 @@ int nand_write_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 da
                        {
                                if (device->device->options & NAND_BUSWIDTH_16)
                                {
-                                       u16 oob_buf = le_to_h_u16(data);
+                                       uint16_t oob_buf = le_to_h_u16(data);
                                        device->controller->write_data(device, oob_buf);
                                        oob += 2;
                                        i += 2;
@@ -1062,7 +1081,7 @@ int nand_write_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 da
 int handle_nand_list_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        nand_device_t *p;
-       int i = 0;
+       int i;
 
        if (!nand_devices)
        {
@@ -1070,13 +1089,17 @@ int handle_nand_list_command(struct command_context_s *cmd_ctx, char *cmd, char
                return ERROR_OK;
        }
 
-       for (p = nand_devices; p; p = p->next)
+       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, 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,\n\t"
+                               "blocksize: %i, blocks: %i",
+                               i, p->device->name, p->manufacturer->name,
+                               p->page_size, p->bus_width,
+                               p->erase_size, p->num_blocks);
                else
-                       command_print(cmd_ctx, "#%i: not probed");
+                       command_print(cmd_ctx, "#%i: not probed", i);
        }
 
        return ERROR_OK;
@@ -1084,29 +1107,34 @@ int handle_nand_list_command(struct command_context_s *cmd_ctx, char *cmd, char
 
 static int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       nand_device_t *p;
        int i = 0;
        int j = 0;
        int first = -1;
        int last = -1;
 
-       if ((argc < 1) || (argc > 3))
-       {
-               return ERROR_COMMAND_SYNTAX_ERROR;
-
-       }
+       nand_device_t *p;
+       int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p);
+       if (ERROR_OK != retval)
+               return retval;
 
-       if (argc == 2)
-       {
-               first = last = strtoul(args[1], NULL, 0);
-       }
-       else if (argc == 3)
-       {
-               first = strtoul(args[1], NULL, 0);
-               last = strtoul(args[2], NULL, 0);
+       switch (argc) {
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       case 1:
+               first = 0;
+               last = INT32_MAX;
+               break;
+       case 2:
+               COMMAND_PARSE_NUMBER(int, args[1], i);
+               first = last = i;
+               i = 0;
+               break;
+       case 3:
+               COMMAND_PARSE_NUMBER(int, args[1], first);
+               COMMAND_PARSE_NUMBER(int, args[2], last);
+               break;
        }
 
-       p = get_nand_device_by_num(strtoul(args[0], NULL, 0));
        if (p)
        {
                if (p->device)
@@ -1138,14 +1166,18 @@ static int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd
                                else
                                        bad_state = " (block condition unknown)";
 
-                               command_print(cmd_ctx, "\t#%i: 0x%8.8x (0x%xkB) %s%s",
-                                                       j, p->blocks[j].offset, p->blocks[j].size / 1024,
-                                                       erase_state, bad_state);
+                               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);
                        }
                }
                else
                {
-                       command_print(cmd_ctx, "#%i: not probed");
+                       command_print(cmd_ctx, "#%s: not probed", args[0]);
                }
        }
 
@@ -1154,15 +1186,16 @@ static int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd
 
 static int handle_nand_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       nand_device_t *p;
-       int retval;
-
        if (argc != 1)
        {
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       p = get_nand_device_by_num(strtoul(args[0], NULL, 0));
+       nand_device_t *p;
+       int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p);
+       if (ERROR_OK != retval)
+               return retval;
+
        if (p)
        {
                if ((retval = nand_probe(p)) == ERROR_OK)
@@ -1178,34 +1211,55 @@ static int handle_nand_probe_command(struct command_context_s *cmd_ctx, char *cm
                        command_print(cmd_ctx, "unknown error when probing NAND flash device");
                }
        }
-       else
-       {
-               command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);
-       }
 
        return ERROR_OK;
 }
 
 static int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       nand_device_t *p;
-       int retval;
-
-       if (argc != 3)
+       if (argc != 1 && argc != 3)
        {
                return ERROR_COMMAND_SYNTAX_ERROR;
 
        }
 
-       p = get_nand_device_by_num(strtoul(args[0], NULL, 0));
+       nand_device_t *p;
+       int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p);
+       if (ERROR_OK != retval)
+               return retval;
+
        if (p)
        {
-               int first = strtoul(args[1], NULL, 0);
-               int last = strtoul(args[2], NULL, 0);
+               unsigned long offset;
+               unsigned long length;
 
-               if ((retval = nand_erase(p, first, last)) == ERROR_OK)
+               /* erase specified part of the chip; or else everything */
+               if (argc == 3) {
+                       unsigned long size = p->erase_size * p->num_blocks;
+
+                       COMMAND_PARSE_NUMBER(ulong, args[1], offset);
+                       if ((offset % p->erase_size) != 0 || offset >= size)
+                               return ERROR_INVALID_ARGUMENTS;
+
+                       COMMAND_PARSE_NUMBER(ulong, args[2], length);
+                       if ((length == 0) || (length % p->erase_size) != 0
+                                       || (length + offset) > size)
+                               return ERROR_INVALID_ARGUMENTS;
+
+                       offset /= p->erase_size;
+                       length /= p->erase_size;
+               } else {
+                       offset = 0;
+                       length = p->num_blocks;
+               }
+
+               retval = nand_erase(p, offset, offset + length - 1);
+               if (retval == ERROR_OK)
                {
-                       command_print(cmd_ctx, "successfully erased blocks %i to %i on NAND flash device '%s'", first, last, p->device->name);
+                       command_print(cmd_ctx, "erased blocks %lu to %lu "
+                                       "on NAND flash device #%s '%s'",
+                                       offset, offset + length,
+                                       args[0], p->device->name);
                }
                else if (retval == ERROR_NAND_OPERATION_FAILED)
                {
@@ -1216,18 +1270,12 @@ static int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cm
                        command_print(cmd_ctx, "unknown error when erasing NAND flash device");
                }
        }
-       else
-       {
-               command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);
-       }
 
        return ERROR_OK;
 }
 
 int handle_nand_check_bad_blocks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       nand_device_t *p;
-       int retval;
        int first = -1;
        int last = -1;
 
@@ -1237,54 +1285,47 @@ int handle_nand_check_bad_blocks_command(struct command_context_s *cmd_ctx, char
 
        }
 
-       if (argc == 3)
-       {
-               first = strtoul(args[1], NULL, 0);
-               last = strtoul(args[2], NULL, 0);
-       }
+       nand_device_t *p;
+       int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p);
+       if (ERROR_OK != retval)
+               return retval;
 
-       p = get_nand_device_by_num(strtoul(args[0], NULL, 0));
-       if (p)
-       {
-               if ((retval = nand_build_bbt(p, first, last)) == ERROR_OK)
-               {
-                       command_print(cmd_ctx, "checked NAND flash device for bad blocks, use \"nand info\" command to list blocks", p->device->name);
-               }
-               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");
-               }
-       }
-       else
+       if (argc == 3)
        {
-               command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);
-       }
+               unsigned long offset;
+               unsigned long length;
 
-       return ERROR_OK;
-}
+               COMMAND_PARSE_NUMBER(ulong, args[1], offset);
+               if (offset % p->erase_size)
+                       return ERROR_INVALID_ARGUMENTS;
+               offset /= p->erase_size;
 
-static int handle_nand_copy_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       nand_device_t *p;
+               COMMAND_PARSE_NUMBER(ulong, args[2], length);
+               if (length % p->erase_size)
+                       return ERROR_INVALID_ARGUMENTS;
 
-       if (argc != 4)
-       {
-               return ERROR_COMMAND_SYNTAX_ERROR;
+               length -= 1;
+               length /= p->erase_size;
 
+               first = offset;
+               last = offset + length;
        }
 
-       p = get_nand_device_by_num(strtoul(args[0], NULL, 0));
-       if (p)
+       retval = nand_build_bbt(p, first, last);
+       if (retval == ERROR_OK)
        {
-
+               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, "NAND flash device '#%s' is out of bounds", args[0]);
+               command_print(cmd_ctx, "unknown error when checking for bad "
+                               "blocks on NAND flash device");
        }
 
        return ERROR_OK;
@@ -1292,9 +1333,9 @@ static int handle_nand_copy_command(struct command_context_s *cmd_ctx, char *cmd
 
 static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       u32 offset;
-       u32 binary_size;
-       u32 buf_cnt;
+       uint32_t offset;
+       uint32_t binary_size;
+       uint32_t buf_cnt;
        enum oob_formats oob_format = NAND_OOB_NONE;
 
        fileio_t fileio;
@@ -1302,24 +1343,25 @@ static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cm
        duration_t duration;
        char *duration_text;
 
-       nand_device_t *p;
-
        if (argc < 3)
        {
                return ERROR_COMMAND_SYNTAX_ERROR;
-
        }
 
-       p = get_nand_device_by_num(strtoul(args[0], NULL, 0));
+       nand_device_t *p;
+       int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p);
+       if (ERROR_OK != retval)
+               return retval;
+
        if (p)
        {
-               u8 *page = NULL;
-               u32 page_size = 0;
-               u8 *oob = NULL;
-               u32 oob_size = 0;
+               uint8_t *page = NULL;
+               uint32_t page_size = 0;
+               uint8_t *oob = NULL;
+               uint32_t oob_size = 0;
                const int *eccpos = NULL;
 
-               offset = strtoul(args[2], NULL, 0);
+               COMMAND_PARSE_NUMBER(u32, args[2], offset);
 
                if (argc > 3)
                {
@@ -1380,7 +1422,7 @@ static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cm
 
                while (buf_cnt > 0)
                {
-                       u32 size_read;
+                       uint32_t size_read;
 
                        if (NULL != page)
                        {
@@ -1394,11 +1436,11 @@ static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cm
 
                        if (oob_format & NAND_OOB_SW_ECC)
                        {
-                               u32 i, j;
-                               u8 ecc[3];
+                               uint32_t i, j;
+                               uint8_t ecc[3];
                                memset(oob, 0xff, oob_size);
                                for (i = 0, j = 0; i < page_size; i += 256) {
-                                       nand_calculate_ecc(p, page+i, ecc);
+                                       nand_calculate_ecc(p, page + i, ecc);
                                        oob[eccpos[j++]] = ecc[0];
                                        oob[eccpos[j++]] = ecc[1];
                                        oob[eccpos[j++]] = ecc[2];
@@ -1411,11 +1453,11 @@ static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cm
                                 * at the end of the OOB area.  It consists
                                 * of 10 bytes per 512-byte data block.
                                 */
-                               u32 i;
-                               u8 *ecc = oob + oob_size - page_size/512 * 10;
+                               uint32_t i;
+                               uint8_t *ecc = oob + oob_size - page_size/512 * 10;
                                memset(oob, 0xff, oob_size);
                                for (i = 0; i < page_size; i += 512) {
-                                       nand_calculate_ecc_kw(p, page+i, ecc);
+                                       nand_calculate_ecc_kw(p, page + i, ecc);
                                        ecc += 10;
                                }
                        }
@@ -1431,7 +1473,7 @@ static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cm
 
                        if (nand_write_page(p, offset / p->page_size, page, page_size, oob, oob_size) != ERROR_OK)
                        {
-                               command_print(cmd_ctx, "failed writing file %s to NAND flash %s at offset 0x%8.8x",
+                               command_print(cmd_ctx, "failed writing file %s to NAND flash %s at offset 0x%8.8" PRIx32 "",
                                        args[1], args[0], offset);
 
                                fileio_close(&fileio);
@@ -1449,29 +1491,27 @@ static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cm
                oob = NULL;
                page = NULL;
                duration_stop_measure(&duration, &duration_text);
-               command_print(cmd_ctx, "wrote file %s to NAND flash %s up to offset 0x%8.8x in %s",
+               command_print(cmd_ctx, "wrote file %s to NAND flash %s up to offset 0x%8.8" PRIx32 " in %s",
                        args[1], args[0], offset, duration_text);
                free(duration_text);
                duration_text = NULL;
        }
-       else
-       {
-               command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);
-       }
 
        return ERROR_OK;
 }
 
 static int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       nand_device_t *p;
-
        if (argc < 4)
        {
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       p = get_nand_device_by_num(strtoul(args[0], NULL, 0));
+       nand_device_t *p;
+       int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p);
+       if (ERROR_OK != retval)
+               return retval;
+
        if (p)
        {
                if (p->device)
@@ -1481,13 +1521,15 @@ static int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd
                        char *duration_text;
                        int retval;
 
-                       u8 *page = NULL;
-                       u32 page_size = 0;
-                       u8 *oob = NULL;
-                       u32 oob_size = 0;
-                       u32 address = strtoul(args[2], NULL, 0);
-                       u32 size = strtoul(args[3], NULL, 0);
-                       u32 bytes_done = 0;
+                       uint8_t *page = NULL;
+                       uint32_t page_size = 0;
+                       uint8_t *oob = NULL;
+                       uint32_t oob_size = 0;
+                       uint32_t address;
+                       COMMAND_PARSE_NUMBER(u32, args[2], address);
+                       uint32_t size;
+                       COMMAND_PARSE_NUMBER(u32, args[3], size);
+                       uint32_t bytes_done = 0;
                        enum oob_formats oob_format = NAND_OOB_NONE;
 
                        if (argc > 4)
@@ -1534,7 +1576,7 @@ static int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd
 
                        while (size > 0)
                        {
-                               u32 size_written;
+                               uint32_t size_written;
                                if ((retval = nand_read_page(p, address / p->page_size, page, page_size, oob, oob_size)) != ERROR_OK)
                                {
                                        command_print(cmd_ctx, "reading NAND flash page failed");
@@ -1567,33 +1609,31 @@ static int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd
                        fileio_close(&fileio);
 
                        duration_stop_measure(&duration, &duration_text);
-                       command_print(cmd_ctx, "dumped %"PRIi64" byte in %s", fileio.size, duration_text);
+                       command_print(cmd_ctx, "dumped %lld byte in %s", fileio.size, duration_text);
                        free(duration_text);
                        duration_text = NULL;
                }
                else
                {
-                       command_print(cmd_ctx, "#%i: not probed");
+                       command_print(cmd_ctx, "#%s: not probed", args[0]);
                }
        }
-       else
-       {
-               command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);
-       }
 
        return ERROR_OK;
 }
 
 static int handle_nand_raw_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       nand_device_t *p;
-
        if ((argc < 1) || (argc > 2))
        {
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       p = get_nand_device_by_num(strtoul(args[0], NULL, 0));
+       nand_device_t *p;
+       int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p);
+       if (ERROR_OK != retval)
+               return retval;
+
        if (p)
        {
                if (p->device)
@@ -1618,13 +1658,9 @@ static int handle_nand_raw_access_command(struct command_context_s *cmd_ctx, cha
                }
                else
                {
-                       command_print(cmd_ctx, "#%i: not probed");
+                       command_print(cmd_ctx, "#%s: not probed", args[0]);
                }
        }
-       else
-       {
-               command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);
-       }
 
        return ERROR_OK;
 }