diff options
author | Dean Glazeski <dnglaze@gmail.com> | 2009-12-17 21:02:39 -0600 |
---|---|---|
committer | David Brownell <dbrownell@users.sourceforge.net> | 2009-12-18 01:33:19 -0800 |
commit | b8b4bb0745b63e03eec745ce0eb97bfa6e0792a1 (patch) | |
tree | ece8e476619329631326ef5b9ec814405c9c8b53 /src | |
parent | 3616b93eee128b0c12fa0d453fbe6ced998e482f (diff) | |
download | openocd+libswd-b8b4bb0745b63e03eec745ce0eb97bfa6e0792a1.tar.gz openocd+libswd-b8b4bb0745b63e03eec745ce0eb97bfa6e0792a1.tar.bz2 openocd+libswd-b8b4bb0745b63e03eec745ce0eb97bfa6e0792a1.tar.xz openocd+libswd-b8b4bb0745b63e03eec745ce0eb97bfa6e0792a1.zip |
NAND read data page refactor.
Added a new function to encapsulate reading a page of data from
a NAND device using either the read_block_data function of a NAND
controller or to use direct reading of data from the NAND device.
This also adds some performance enhancements and uses the read_data
function if the read_block_data function fails safely (because it
can't allocate a buffer in the working area).
[dbrownell@users.sourceforge.net: fix fault handling, whitespace]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/flash/nand/core.c | 68 | ||||
-rw-r--r-- | src/flash/nand/core.h | 2 |
2 files changed, 25 insertions, 45 deletions
diff --git a/src/flash/nand/core.c b/src/flash/nand/core.c index d52cf5df..1056696d 100644 --- a/src/flash/nand/core.c +++ b/src/flash/nand/core.c @@ -768,11 +768,31 @@ int nand_page_command(struct nand_device *nand, uint32_t page, return ERROR_OK; } +int nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t size) +{ + int retval = ERROR_NAND_NO_BUFFER; + + if (nand->controller->read_block_data != NULL) + retval = (nand->controller->read_block_data)(nand, data, size); + + if (ERROR_NAND_NO_BUFFER == retval) { + uint32_t i; + int incr = (nand->device->options & NAND_BUSWIDTH_16) ? 2 : 1; + + retval = ERROR_OK; + for (i = 0; retval == ERROR_OK && i < size; i += incr) { + retval = nand->controller->read_data(nand, data); + data += incr; + } + } + + return retval; +} + int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) { - uint32_t i; int retval; retval = nand_page_command(nand, page, NAND_CMD_READ0, !data); @@ -780,52 +800,10 @@ int nand_read_page_raw(struct nand_device *nand, uint32_t page, return retval; if (data) - { - if (nand->controller->read_block_data != NULL) - (nand->controller->read_block_data)(nand, data, data_size); - else - { - for (i = 0; i < data_size;) - { - if (nand->device->options & NAND_BUSWIDTH_16) - { - nand->controller->read_data(nand, data); - data += 2; - i += 2; - } - else - { - nand->controller->read_data(nand, data); - data += 1; - i += 1; - } - } - } - } + nand_read_data_page(nand, data, data_size); if (oob) - { - if (nand->controller->read_block_data != NULL) - (nand->controller->read_block_data)(nand, oob, oob_size); - else - { - for (i = 0; i < oob_size;) - { - if (nand->device->options & NAND_BUSWIDTH_16) - { - nand->controller->read_data(nand, oob); - oob += 2; - i += 2; - } - else - { - nand->controller->read_data(nand, oob); - oob += 1; - i += 1; - } - } - } - } + nand_read_data_page(nand, oob, oob_size); return ERROR_OK; } diff --git a/src/flash/nand/core.h b/src/flash/nand/core.h index b8dc01c7..990114ad 100644 --- a/src/flash/nand/core.h +++ b/src/flash/nand/core.h @@ -211,6 +211,8 @@ struct nand_device *get_nand_device_by_num(int num); int nand_page_command(struct nand_device *nand, uint32_t page, uint8_t cmd, bool oob_only); +int nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t size); + int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); int nand_write_page_raw(struct nand_device *nand, uint32_t page, |