summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDean Glazeski <dnglaze@gmail.com>2009-12-17 21:02:39 -0600
committerDavid Brownell <dbrownell@users.sourceforge.net>2009-12-18 01:33:19 -0800
commitb8b4bb0745b63e03eec745ce0eb97bfa6e0792a1 (patch)
treeece8e476619329631326ef5b9ec814405c9c8b53 /src
parent3616b93eee128b0c12fa0d453fbe6ced998e482f (diff)
downloadopenocd+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.c68
-rw-r--r--src/flash/nand/core.h2
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,