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>
This commit is contained in:
Dean Glazeski 2009-12-17 21:02:39 -06:00 committed by David Brownell
parent 3616b93eee
commit b8b4bb0745
2 changed files with 25 additions and 45 deletions

View File

@ -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;
}

View File

@ -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,