#include <cyg/io/nand_bbt.h>
#include <redboot.h>
#include <stdlib.h>
-#if 0
-static int nfc_debug = 1;
-#endif
#include CYGHWR_MEMORY_LAYOUT_H
static int g_nfc_debug_level = NFC_DEBUG_NONE;
static bool g_nfc_debug_measure = false;
static bool g_is_2k_page = false;
-static unsigned long g_block_offset;
+static unsigned int g_block_offset;
static bool g_is_4k_page = false;
static unsigned int g_nfc_version = MXC_NFC_V1; // default to version 1.0
static int num_of_nand_chips = 1;
#define BLOCK_TO_OFFSET(blk) ((blk) * NF_PG_PER_BLK * NF_PG_SZ)
#define BLOCK_TO_PAGE(blk) ((blk) * NF_PG_PER_BLK)
#define BLOCK_PAGE_TO_OFFSET(blk, pge) (((blk) * NF_PG_PER_BLK + (pge)) * NF_PG_SZ)
-#define OFFSET_TO_BLOCK(offset) (((offset) / NF_PG_SZ) / NF_PG_PER_BLK)
-#define OFFSET_TO_PAGE(offset) (((offset) / NF_PG_SZ) % NF_PG_PER_BLK)
+#define OFFSET_TO_BLOCK(offset) ((u32)((offset) / (NF_PG_SZ * NF_PG_PER_BLK)))
+#define OFFSET_TO_PAGE(offset) ((u32)((offset) / NF_PG_SZ) % NF_PG_PER_BLK)
static u8 *g_bbt, *g_page_buf;
static u32 g_bbt_sz;
// this callback allows the platform specific iomux setup
nfc_iomuxsetup_func_t *nfc_iomux_setup = NULL;
+static flash_addr_t flash_region_start;
+static flash_addr_t flash_region_end;
+static int flash_enable;
+
+/* This assumes reading the flash with monotonically increasing flash addresses */
+static flash_addr_t nfc_l_to_p(flash_addr_t addr)
+{
+ if (g_block_offset == 0) {
+ return addr & MXC_NAND_ADDR_MASK;
+ } else {
+ flash_addr_t ra;
+ u32 block = (addr & MXC_NAND_ADDR_MASK) / NF_BLK_SZ;
+ u32 offset = addr % NF_BLK_SZ;
+
+ ra = (block + g_block_offset) * NF_BLK_SZ + offset;
+ if (offset == 0) {
+ nfc_printf(NFC_DEBUG_MIN,
+ "Remapping block %u at addr 0x%08llx to block %u at addr 0x%08llx\n",
+ block, (u64)addr, block + g_block_offset, (u64)ra);
+ }
+ return ra;
+ }
+}
+
+static int flash_addr_valid(flash_addr_t addr)
+{
+ if (!flash_enable) {
+ nfc_printf(NFC_DEBUG_MIN, "No flash area enabled\n");
+ return 1;
+ }
+ if (addr < flash_region_start || addr >= flash_region_end) {
+ diag_printf("Flash address 0x%08llx is outside valid region 0x%08llx..0x%08llx\n",
+ (u64)addr, (u64)flash_region_start, (u64)flash_region_end);
+ return 0;
+ }
+ return 1;
+}
+
+/* FIXME: we should pass flash_addr_t as arguments */
+void mxc_flash_enable(void *start, void *end)
+{
+ flash_addr_t s = (unsigned long)start & MXC_NAND_ADDR_MASK;
+ flash_addr_t e = (unsigned long)end & MXC_NAND_ADDR_MASK;
+
+ if (flash_enable++ == 0) {
+ flash_region_start = s;
+ flash_region_end = e;
+ diag_printf1("Enabling flash region 0x%08llx..0x%08llx\n",
+ (u64)s, (u64)e);
+ g_block_offset = 0;
+ } else {
+ if (s < flash_region_start ||
+ e > flash_region_end) {
+ diag_printf("** WARNING: Enable 0x%08llx..0x%08llx outside enabled flash region 0x%08llx..0x%08llx\n",
+ (u64)s, (u64)e, (u64)flash_region_start, (u64)flash_region_end);
+ }
+ }
+}
+
+void mxc_flash_disable(void *start, void *end)
+{
+ flash_addr_t s = (unsigned long)start & MXC_NAND_ADDR_MASK;
+ flash_addr_t e = (unsigned long)end & MXC_NAND_ADDR_MASK;
+
+ if (flash_enable) {
+ if (--flash_enable == 0) {
+ diag_printf1("Disabling flash region 0x%08llx..0x%08llx\n",
+ (u64)s, (u64)e);
+ if (s != flash_region_start ||
+ e != flash_region_end) {
+ diag_printf("** Error: Disable 0x%08llx..0x%08llx not equal to enabled flash region 0x%08llx..0x%08llx\n",
+ (u64)s, (u64)e, (u64)flash_region_start, (u64)flash_region_end);
+ }
+ }
+ } else {
+ diag_printf("** Error: unbalanced call to flash_disable()\n");
+ }
+}
+
int
#ifndef MXCFLASH_SELECT_MULTI
flash_hwr_init(void)
res = (buf[off] >> sft) & 0x3;
if (res) {
addr = BLOCK_TO_OFFSET(block);
- diag_printf1("Block %u at %08llx is marked %s (%d) in BBT@%p[%02x] mask %02x\n",
+ diag_printf1("Block %u at 0x%08llx is marked %s (%d) in BBT@%p[%02x] mask %02x\n",
block, (u64)addr, res == BLK_RESERVED ? "reserved" :
res == BLK_BAD_FACTORY ? "factory bad" : "runtime bad",
res, buf, off, 3 << sft);
*/
int nfc_erase_region(flash_addr_t addr, u32 len, bool skip_bad, bool verbose)
{
- u32 sz, blk, update = 0, skip = 0, j = 0;
+ u32 sz, blk, update = 0, j = 0;
nfc_printf(NFC_DEBUG_MED, "%s: addr=0x%08llx len=0x%08x\n",
__FUNCTION__, (u64)addr, len);
addr &= MXC_NAND_ADDR_MASK;
// now addr has to be block aligned
for (sz = 0; sz < len; addr += NF_BLK_SZ, j++, sz += NF_BLK_SZ) {
+ if (!flash_addr_valid(addr)) {
+ return 0;
+ }
blk = OFFSET_TO_BLOCK(addr);
if (skip_bad && nfc_is_badblock(blk, g_bbt)) {
- if (skip++ >= flash_dev_info->max_bad_blk) {
- diag_printf("\nToo many bad blocks encountered\n");
- return FLASH_ERR_PROTOCOL;
- }
diag_printf("\nSkipping bad block %u at addr 0x%08llx\n",
blk, (u64)addr);
continue;
}
if (nfc_erase_blk(addr) != 0) {
- diag_printf("\nError: Failed to erase block %u at addr 0x%08llx\n",
+ diag_printf("\n** Error: Failed to erase block %u at addr 0x%08llx\n",
blk, (u64)addr);
mark_blk_bad(blk, g_bbt, BLK_BAD_RUNTIME);
// we don't need to update the table immediately here since even
if (update) {
if (program_bbt_to_flash() != 0) {
diag_printf("\nError: Failed to update bad block table\n");
- return -1;
+ return FLASH_ERR_PROGRAM;
}
diag_printf("\nnew bad blocks=%d\n", update);
}
*/
int nfc_program_region(flash_addr_t addr, u8 *buf, u32 len)
{
- u32 sz, blk, update = 0, skip = 0, partial_block_size;
+ u32 sz, blk, update = 0, partial_block_size;
- diag_printf1("%s: addr=0x%08llx, len=0x%08x\n", __FUNCTION__, (u64)addr, len);
+ nfc_printf(NFC_DEBUG_MED, "%s: addr=0x%08llx, len=0x%08x\n",
+ __FUNCTION__, (u64)addr, len);
if ((addr % (NF_PG_SZ / num_of_nand_chips)) != 0) {
diag_printf("Error: flash address 0x%08llx not page aligned\n", (u64)addr);
partial_block_size = addr % NF_BLK_SZ;
- addr &= MXC_NAND_ADDR_MASK;
- // now addr has to be block aligned
+ mxc_nfc_buf_clear(NAND_SPAR_BUF0, 0xff, NF_SPARE_SZ);
+ addr = nfc_l_to_p(addr);
while (1) {
+ if (!flash_addr_valid(addr)) {
+ diag_printf("\nToo many bad blocks in flash region 0x%08llx..0x%08llx\n",
+ (u64)flash_region_start, (u64)flash_region_end);
+ return FLASH_ERR_INVALID;
+ }
blk = OFFSET_TO_BLOCK(addr);
if (nfc_is_badblock(blk, g_bbt)) {
- if (skip++ >= flash_dev_info->max_bad_blk) {
- diag_printf("\nToo many bad blocks encountered\n");
- return FLASH_ERR_PROTOCOL;
- }
diag_printf("\nSkipping bad block %u at addr 0x%08llx\n", blk, addr);
goto incr_address;
}
diag_printf("\nError: Failed to program flash block %u at addr 0x%08llx\n",
blk, (u64)addr);
mark_blk_bad(blk, g_bbt, BLK_BAD_RUNTIME);
- if (skip + update > flash_dev_info->max_bad_blk) {
- diag_printf("\nToo many bad blocks encountered\n");
- return FLASH_ERR_PROTOCOL;
- }
// we don't need to update the table immediately here since even
// with power loss now, we should see the same program error again.
goto incr_address;
incr_address:
addr += partial_block_size;
partial_block_size = NF_BLK_SZ;
+ g_block_offset++;
}
if (update) {
if (program_bbt_to_flash() != 0) {
diag_printf("\nError: Failed to update bad block table\n");
return -1;
}
- diag_printf("\nnew bad blocks: %d\n", update);
}
- if (skip)
- diag_printf("\nbad blocks skipped: %d\n", skip);
-
return FLASH_ERR_OK;
}
* in flash address will be masked off inside the function.
* It skips bad blocks and read good blocks of data for "len" bytes.
*
- * @param addr NAND flash address. it has to be page aligned
+ * @param addr NAND flash address.
* @param buf memory buf where data will be copied to
* @param len number of bytes
* @return FLASH_ERR_OK (0) if successful; non-zero otherwise
*/
int nfc_read_region(flash_addr_t addr, u8 *buf, u32 len)
{
- u32 blk, bad = 0, start_point = 0, pg_no;
- unsigned long offset = addr % NF_PG_SZ;
+ u32 start_point = 0, pg_no;
+ unsigned int offset = addr % NF_PG_SZ;
+ int chk_bad = 1;
- diag_printf1("%s: addr=0x%08llx, buf=0x%p, len=0x%08x\n",
- __FUNCTION__, addr, buf, len);
+ nfc_printf(NFC_DEBUG_MED, "%s: addr=0x%08llx, offset=%03x buf=0x%p, len=0x%08x\n",
+ __FUNCTION__, addr, offset, buf, len);
+ addr = nfc_l_to_p(addr);
if (addr < (u32)flash_info.start || (addr + len) > (u32)flash_info.end || len == 0) {
- diag_printf("Error: flash address 0x%08llx..0x%08llx outside valid range %p..%p\n",
+ diag_printf("** Error: flash address 0x%08llx..0x%08llx outside valid range %p..%p\n",
(u64)addr, (u64)addr + len - 1, flash_info.start, flash_info.end);
return FLASH_ERR_INVALID;
}
- addr = (addr & MXC_NAND_ADDR_MASK) - offset;
- blk = OFFSET_TO_BLOCK(addr);
while (len > 0) {
int i;
- if ((addr % NF_BLK_SZ) == 0) {
- // only need to test block aligned page address
- blk = OFFSET_TO_BLOCK(addr);
+ if (!flash_addr_valid(addr)) {
+ diag_printf("Too many bad blocks in flash region 0x%08llx..0x%08llx\n",
+ (u64)flash_region_start, (u64)flash_region_end);
+ return FLASH_ERR_INVALID;
+ }
+ if (chk_bad) {
+ int blk = OFFSET_TO_BLOCK(addr);
+
if (nfc_is_badblock(blk, g_bbt)) {
- if (bad++ >= flash_dev_info->max_bad_blk) {
- diag_printf("\nToo many bad blocks encountered\n");
- return FLASH_ERR_PROTOCOL;
- }
- diag_printf("\nSkipping bad block %u at addr 0x%08llx\n", blk, (u64)addr);
+ diag_printf("Skipping bad block %u at addr 0x%08llx\n", blk, (u64)addr);
addr += NF_BLK_SZ;
+ g_block_offset++;
continue;
}
+ chk_bad = 0;
}
pg_no = addr / NF_PG_SZ;
- if ((addr % NF_PG_SZ) != 0) {
+ if (offset != 0) {
/* Find which interleaved NAND device */
- start_point = (addr - (pg_no * NF_PG_SZ)) / (NF_PG_SZ / num_of_nand_chips);
+ start_point = offset / (NF_PG_SZ / num_of_nand_chips);
} else {
start_point = 0;
}
for (i = start_point; i < num_of_nand_chips; i++) {
- int chunk_size = len > NF_PG_SZ / num_of_nand_chips ?
- NF_PG_SZ / num_of_nand_chips : len;
+ int chunk_size = (NF_PG_SZ - offset) / num_of_nand_chips;
+ if (chunk_size > len)
+ chunk_size = len;
+ nfc_printf(NFC_DEBUG_MED, "Reading page %d addr 0x%08llx chip %d len 0x%03x\n",
+ pg_no, (u64)addr, i, chunk_size);
if (nfc_read_page(i, pg_no, 0) != 0) {
- diag_printf("\nError: Failed to read flash block %u at addr 0x%08llx\n",
- blk, (u64)addr);
+ diag_printf("** Error: Failed to read flash block %u at addr 0x%08llx\n",
+ OFFSET_TO_BLOCK(addr), (u64)addr);
return FLASH_ERR_INVALID;
}
// now do the copying
- nfc_buf_read(buf, NAND_MAIN_BUF0, chunk_size);
+ nfc_buf_read(buf, NAND_MAIN_BUF0 + offset, chunk_size);
buf += chunk_size;
len -= chunk_size;
addr += NF_PG_SZ / num_of_nand_chips - offset;
offset = 0;
}
+ chk_bad = (addr % NF_BLK_SZ) == 0;
}
return FLASH_ERR_OK;
u8 t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0;
int res = 0;
+ nfc_printf(NFC_DEBUG_MAX, "%s: reading page %u offset 0x%03x (addr 0x%08llx)\n",
+ __FUNCTION__, pg_no, pg_off, (flash_addr_t)pg_no * NF_PG_SZ + pg_off);
+
if (ecc_force == ECC_FORCE_OFF || pg_off != 0 )
ecc = 0;
if (ecc && ((t1 & 0xA) != 0x0 || (t2 & 0xA) != 0x0 ||
(t3 & 0xA) != 0x0 || (t4 & 0xA) != 0x0)) {
- diag_printf("\n** Error: %s(page=%d, col=%d): ECC status=0x%x:0x%x:0x%x:0x%x\n",
- __FUNCTION__, pg_no, pg_off, t1, t2, t3, t4);
+ diag_printf("\n** Error: ECC error page %u, col %u: ECC status=0x%x:0x%x:0x%x:0x%x\n",
+ pg_no, pg_off, t1, t2, t3, t4);
res = -1;
goto out;
}
NF_PG_PER_BLK, NF_PG_SZ);
}
-static inline void mxc_clr_block_offset(void *start, void *end)
-{
- nfc_printf(NFC_DEBUG_MIN, "Clearing block offset %lu for %p..%p\n",
- g_block_offset, start, end);
- g_block_offset = 0;
-}
-
-static void *flash_region_start;
-static void *flash_region_end;
-static int flash_enable;
-
-void mxc_flash_enable(void *start, void *end)
-{
- if (flash_enable++ == 0) {
- flash_region_start = start;
- flash_region_end = end;
- mxc_clr_block_offset(start, end);
- } else {
- if (start < flash_region_start || end > flash_region_end) {
- diag_printf("** WARNING: Enable %p..%p outside enabled flash region %p..%p\n",
- start, end, flash_region_start, flash_region_end);
- }
- }
-}
-
-void mxc_flash_disable(void *start, void *end)
-{
- if (flash_enable) {
- if (--flash_enable == 0) {
- if (start != flash_region_start || end != flash_region_end) {
- diag_printf("** Error: Disable %p..%p not equal to enabled flash region %p..%p\n",
- start, end, flash_region_start, flash_region_end);
- }
- }
- } else {
- diag_printf("** Error: unbalanced call to flash_disable()\n");
- }
-}
-
static int mxc_nfc_isbad_bbt(u16 *bbt, int block)
{
cyg_uint8 res;
local_cmd_entry("show",
"Show a page main/spare areas or spare area only (-s)",
- "-f <raw page address> [-s]",
+ "-f <raw page address> | -b <block> [-s]",
nand_show,
NAND_cmds
);
static u32 curr_addr;
static void nand_show(int argc, char *argv[])
{
- u32 ra;
+ u32 ra, block;
bool flash_addr_set = false;
+ bool block_set = false;
bool spar_only = false;
- struct option_info opts[2];
+ struct option_info opts[3];
init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM,
&ra, &flash_addr_set, "NAND FLASH memory byte address");
- init_opts(&opts[1], 's', false, OPTION_ARG_TYPE_FLG,
+ init_opts(&opts[1], 'b', true, OPTION_ARG_TYPE_NUM,
+ &block, &block_set, "NAND FLASH memory block number");
+ init_opts(&opts[2], 's', false, OPTION_ARG_TYPE_FLG,
&spar_only, NULL, "Spare only");
- if (!scan_opts(argc, argv, 2, opts, 2, 0, 0, 0)) {
+ if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
return;
}
- if (!flash_addr_set) {
+ if (flash_addr_set && block_set) {
+ nand_usage("options -f and -b are mutually exclusive");
+ return;
+ } else if (flash_addr_set) {
+ curr_addr = ra;
+ } else if (block_set) {
+ ra = BLOCK_TO_OFFSET(block) + (unsigned long)flash_info.start;
+ curr_addr = ra;
+ } else {
ra = curr_addr;
curr_addr += NF_PG_SZ;
- } else {
- curr_addr = ra;
}
if (ra % NF_PG_SZ) {
init_opts(&opts[3], 'c', true, OPTION_ARG_TYPE_NUM,
&col, &col_set, "column addr");
- if (!scan_opts(argc, argv, 2, opts, 4, 0, 0, 0)) {
+ if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
nand_usage("invalid arguments");
return;
}
diag_printf("\n** Error: flash address: 0x%08x out of range\n", ra);
return;
}
+ if (nfc_is_badblock(OFFSET_TO_BLOCK(ra), g_bbt)) {
+ diag_printf("\nSkipping bad block %u at addr=0x%08llx\n",
+ OFFSET_TO_BLOCK(ra), (u64)ra);
+ ra = (OFFSET_TO_BLOCK(ra) + 1) * NF_BLK_SZ;
+ continue;
+ }
pg_no = ra / NF_PG_SZ;
pg_off = ra % NF_PG_SZ;
for (i = 0; i < num_of_nand_chips; i++) {
bool col_set = false;
struct option_info opts[4];
bool ecc_status = g_ecc_enable;
- int skip = 0;
init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
&mem_addr, &mem_addr_set, "memory base address");
&len, &length_set, "image length [in FLASH]");
init_opts(&opts[3], 'c', true, OPTION_ARG_TYPE_NUM,
&col, &col_set, "column addr");
- if (!scan_opts(argc, argv, 2, opts, 4, 0, 0, 0)) {
+ if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
nand_usage("invalid arguments");
return;
}
}
if ((mem_addr < (CYG_ADDRESS)ram_start) ||
- ((mem_addr+len) >= (CYG_ADDRESS)ram_end)) {
- diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
+ ((mem_addr + len) >= (CYG_ADDRESS)ram_end)) {
+ diag_printf("** WARNING: RAM address range: %p..%p may be invalid\n",
+ (void *)mem_addr, (void *)(mem_addr + len));
diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
}
mem_addr_st = mem_addr;
len_st = len;
ra &= MXC_NAND_ADDR_MASK;
+
+ mxc_nfc_buf_clear(NAND_SPAR_BUF0, 0xff, NF_SPARE_SZ);
do {
if (OFFSET_TO_BLOCK(ra) > (NF_BLK_CNT - 1)) {
- diag_printf("Out of range: addr=0x%x\n", ra);
+ diag_printf("\nFlash address 0x%08x out of range\n", ra);
return;
}
if (nfc_is_badblock(OFFSET_TO_BLOCK(ra), g_bbt)) {
- if (skip++ >= flash_dev_info->max_bad_blk) {
- diag_printf("\nToo many bad blocks encountered\n");
- return;
- }
diag_printf("\nSkipping bad block %u at addr=0x%08llx\n",
OFFSET_TO_BLOCK(ra), (u64)ra);
ra = (OFFSET_TO_BLOCK(ra) + 1) * NF_BLK_SZ;
}
if (nfc_write_pg_random(ra / NF_PG_SZ, ra % NF_PG_SZ, (u8 *)mem_addr, 0) != 0) {
if (g_nfc_debug_level >= NFC_DEBUG_DEF) {
- diag_printf("Warning %d: program error at addr 0x%x\n", __LINE__, ra);
+ diag_printf("\nWarning %d: program error at addr 0x%x\n", __LINE__, ra);
}
mark_blk_bad(OFFSET_TO_BLOCK(ra), g_bbt, BLK_BAD_RUNTIME);
ra = (OFFSET_TO_BLOCK(ra) + 1) * NF_BLK_SZ; //make sure block size aligned
- mem_addr = mem_addr_st; // rewind to blocl boundary
+ mem_addr = mem_addr_st; // rewind to block boundary
len = len_st;
continue;
}
ra += NF_PG_SZ;
mem_addr += NF_PG_SZ;
} while (len > 0);
- if (skip) {
- diag_printf("\n%s(skip bad blocks=%d\n\n", __FUNCTION__, skip);
- }
diag_printf("\n");
}
init_opts(&opts[2], 'o', false, OPTION_ARG_TYPE_FLG,
&force_erase_set, &force_erase_set, "force erases block");
- if (!scan_opts(argc, argv, 2, opts, 4, 0, 0, 0)) {
+ if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
nand_usage("invalid arguments");
return;
}
nand_usage("missing argument");
return;
}
- if ((ra % NF_BLK_SZ) != 0 ||
- (len % NF_BLK_SZ) != 0 || len == 0) {
- diag_printf("Address or length is not block aligned or length is zero!\n");
+ if ((ra % NF_BLK_SZ) != 0) {
+ diag_printf("Address must be block aligned!\n");
+ diag_printf("Block size is 0x%x\n", NF_BLK_SZ);
+ return;
+ }
+ if ((len % NF_BLK_SZ) != 0) {
+ diag_printf("length must be block aligned!\n");
diag_printf("Block size is 0x%x\n", NF_BLK_SZ);
return;
}
+ if (len == 0) {
+ diag_printf("length must be > 0!\n");
+ return;
+ }
- if (!verify_action("About to erase 0x%x bytes from nand offset 0x%x\n", len, ra)) {
+ if (!verify_action("About to erase 0x%08x bytes from nand offset 0x%08x", len, ra)) {
diag_printf("** Aborted\n");
return;
}
- // now ra is block aligned
if (force_erase_set == true) {
diag_printf("Force erase ...");
nfc_erase_region(ra, len, 0, 1);
init_opts(&opts[1], 'r', false, OPTION_ARG_TYPE_FLG,
&force_rescan, NULL, "force low level re-scan");
- if (!scan_opts(argc, argv, 2, opts, 2, 0, 0, 0)) {
+ if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
nand_usage("invalid arguments");
return;
}
for (i = 0; i < NF_BLK_CNT; i++) {
int res = nfc_is_badblock(i, g_bbt);
if (res & ~BLK_RESERVED) {
- diag_printf("block %d at offset 0x%x is a %s bad block\n",
+ diag_printf("block %d at offset 0x%08x is a %s bad block\n",
i, i * NF_BLK_SZ, res == BLK_BAD_FACTORY ? "factory" : "runtime");
j++;
}
diag_printf("Non page-aligned read not supported here: 0x%x\n", addr);
return;
}
- if (spare_only) {
- diag_printf("Error %d: Not supported\n", __LINE__);
- return;
- } else {
- pg_no = addr / NF_PG_SZ;
- pg_off = addr % NF_PG_SZ;
- for (i = 0; i < num_of_nand_chips; i++) {
- if (nfc_read_page(i, pg_no, pg_off) != 0) {
- diag_printf("Error %d: uncorrectable. But still printing ...\n", __LINE__);
- }
- pg_off = 0;
- diag_printf("\n============ Printing block(%d) page(%d) ==============\n",
- blk_num, pg_num);
-
- diag_printf("<<<<<<<<< spare area >>>>>>>>>\n");
- print_pkt_16((u16*)NAND_SPAR_BUF0, NF_SPARE_SZ);
+ pg_no = addr / NF_PG_SZ;
+ pg_off = addr % NF_PG_SZ;
+ for (i = 0; i < num_of_nand_chips; i++) {
+ if (nfc_read_page(i, pg_no, pg_off) != 0) {
+ diag_printf("Error %d: uncorrectable. But still printing ...\n", __LINE__);
+ }
+ pg_off = 0;
+ diag_printf("\n============ Printing block(%d) page(%d) ==============\n",
+ blk_num, pg_num);
- if (!spare_only) {
- diag_printf("<<<<<<<<< main area >>>>>>>>>\n");
- print_pkt_16((u16*)NAND_MAIN_BUF0, NF_PG_SZ / num_of_nand_chips);
- }
+ diag_printf("<<<<<<<<< spare area >>>>>>>>>\n");
+ print_pkt_16((u16*)NAND_SPAR_BUF0, NF_SPARE_SZ);
- diag_printf("\n");
+ if (!spare_only) {
+ diag_printf("<<<<<<<<< main area >>>>>>>>>\n");
+ print_pkt_16((u16*)NAND_MAIN_BUF0, NF_PG_SZ / num_of_nand_chips);
}
+
+ diag_printf("\n");
}
}