jnand_testnand.c
来自「QUALCOMM JNAND DRIVER」· C语言 代码 · 共 372 行
C
372 行
/**********************************************************************
* jnand_testnand.c
*
* Tests run to test the NAND device driver layer
*
*
* Copyright (C) 2002, Qualcomm, Inc.
*
**********************************************************************/
/*===========================================================================
EDIT HISTORY FOR MODULE
This section contains comments describing changes made to the module.
Notice that changes are listed in reverse chronological order.
$Header: //depot/asic/msmshared/tools/jnand/jnand_testnand.c#3 $ $DateTime: 2003/08/29 14:06:58 $ $Author: dionh $
when who what, where, why
-------- --- ----------------------------------------------------------
2003-08-29 drh Add KICK_WATCHDOG liberally throughout.
Add new test that will only check and inform of bad
block status.
2003-08-27 drh Taken from EFS2 test framework to become part of JNAND
so that we do not have to test device drivers as part of
DMSS, but only as part of JNAND, which is simpler.
2002-09-05 gr Added an is_block_erased function since this has been
removed from fs_nand_device.c. Added a test for ECC error
conditions.
2002-09-01 drh Changed test to use nand_dev->is_erased instead of checking
here.
2002-08-15 drh Changed nand_device to nand_dev to resolve multiple definition
2002-08-15 drh Added spinners or block number printing as output
2002-08-08 drh Created
===========================================================================*/
#include "jnand.h"
#include "jnand_msm.h"
/********************************************************************
* Main test task function
*******************************************************************/
/* defines to control what code gets compiled in
* so we do not have to edit the makefile all the time
* to change the behavior of the test */
#define RUN_PATTERN
#define RUN_PATTERN_VERBOSE
/* These two are mutually exclusive */
#undef PRINT_SPINNERS
#define PRINT_BLOCKNOS
#if defined(PRINT_SPINNERS) && defined(PRINT_BLOCKNOS)
#error PRINT_SPINNERS and PRINT_BLOCKNOS are mutually exclusive
#endif
/* number of different characters to use to create spinners */
#define NUM_SPINNERS 6
/* Maximum size that sectors and pages can be. Must use
* this to define array sizes with
*/
#define MAX_SECTOR_SIZE 512
#define SPARE_SIZE 16
#define TOTAL_PAGE_SIZE (MAX_PAGE_SIZE+SPARE_SIZE)
/********************************************************************
* Global data
*******************************************************************/
/* NAND device structure */
struct fs_device_data * nand_dev = 0;
char patterns[] =
{
#ifdef PATTERN_LARGE
#error code not present
#else
0x50, 0xf0, 0x0f,
#endif
};
/* data to make spinning "alive" indicator */
/* {'|', '/', '-', '|', '\', '-'} */
char spinners[NUM_SPINNERS] = {0x7C, 0x2F, 0x2D, 0X7C, 0x5C, 0x2D};
/* Buffers to store page data in for reading and writing */
static unsigned char pbuf[TOTAL_PAGE_SIZE];
static unsigned char rbuf[TOTAL_PAGE_SIZE];
/***********************************************************************
FUNCTION is_block_erased
DESCRIPTION This function checks if every byte of every page in a given
block is erased by repeatedly calling the is_page_erased
function.
DEPENDENCIES None
RETURN VALUE TRUE if block is erased
FALSE if block is not erased, or any error occurs during
checking
**********************************************************************/
static int
is_block_erased (fs_device_t self, block_id block)
{
int i;
int block_size = self->block_size (self);
page_id start_page_no;
start_page_no = (page_id) (block * block_size);
for (i = 0; i < block_size; i++)
{
if (!self->is_erased (self, start_page_no+i))
return FALSE;
}
return TRUE;
} /* END is_block_erased */
/********************************************************************
* Function to run patterns over the flash
*******************************************************************/
fatal_code_type
do_pattern (int blockno, char patternval)
{
int i, j;
page_id current_page;
int vfail = 0;
KICK_WATCHDOG();
if (nand_dev->bad_block_check(nand_dev, blockno) ==
FS_DEVICE_BAD_BLOCK)
{
printf ("\n--- Skipping: bad block %d\n", blockno);
return ERR_BAD_BLOCK;
}
else
{
//printf ("\ngood block %d\n", blockno);
}
/* erase the block */
if (nand_dev->erase_block(nand_dev, blockno) != FS_DEVICE_DONE)
{
printf ("--- Error: device failed during erase of block %d\n",
blockno);
return ERR_ERASE_FAIL;
}
/* Make sure the block was actually erased */
if ((is_block_erased (nand_dev, blockno)) != TRUE)
{
return ERR_ERASE_FAIL;
}
#ifdef RUN_PATTERN
current_page = blockno * pages_in_block;
KICK_WATCHDOG();
/* run pattern over every page in the block we just erased */
for (j=0; j<pages_in_block; j++)
{
KICK_WATCHDOG();
if (nand_dev->write_page (nand_dev, current_page, pbuf)
!= FS_DEVICE_DONE )
{
printf ("--- Error: device failed during write of page 0x%x\n",
current_page);
return ERR_WRITE_FAIL;
}
/* clear out readback buffer with pattern we do not use */
for (i=0; i<page_size; i++)
{
rbuf[i] = 3;
}
/* read back data and verify it against source */
if (nand_dev->read_page (nand_dev, current_page, rbuf)
!= FS_DEVICE_DONE )
{
printf ("Error: read fail of page 0x%x\n", current_page);
return ERR_READ_FAIL;
}
for (i=0; i<page_size; i++)
{
if (pbuf[i] != rbuf[i])
{
#ifdef RUN_PATTERN_VERBOSE
printf (" Verify fail at index %d in page %d, src 0x%x read 0x%x \n",
i, current_page, pbuf[i], rbuf[i]);
#endif
vfail = 1;
// return ERR_VERIFY_FAIL;
}
}
current_page++;
}
if (vfail != 0)
{
return ERR_VERIFY_FAIL;
}
else
{
return ERR_OK;
}
#endif /* RUN_PATTERN */
#if !defined(RUN_PATTERN)
return ERR_OK;
#endif
}
/********************************************************************
* Main procedure of the NAND device driver layer test
*******************************************************************/
void
nand_test (void)
{
int i;
#ifndef RUN_BAD_FINDER
int j, p;
unsigned int pass = 0;
int result;
int numpats = sizeof(patterns);
#endif
#ifdef PRINT_SPINNERS
int spinindex = 0;
#endif
printf ("EFS2 NAND test started!\n");
nand_dev=fs_nand_device_probe();
if ( nand_dev == (struct fs_device_data *)FS_NO_DEVICE)
{
printf("Error: no nand_device found \n");
return;
}
else
{
flash_name = nand_dev->device_name(nand_dev);
printf("Found %s\n", flash_name);
/* get some information about the device */
block_count = nand_dev->block_count(nand_dev);
pages_in_block = nand_dev->block_size(nand_dev);
page_size = nand_dev->page_size(nand_dev);
flash_name = nand_dev->device_name(nand_dev);
/* calculate size of eraseable unit and max number of pages */
eu_size = pages_in_block * page_size;
max_pages = block_count * pages_in_block;
}
#ifndef RUN_BAD_FINDER
do
{
pass++;
printf("\n++++ Pass 0x%x\n", pass);
KICK_WATCHDOG();
for (p=0; p<numpats ; p++)
{
/* init pattern buffer */
for (j=0; j<MAX_PAGE_SIZE; j++)
{
pbuf[j] = patterns[p];
}
KICK_WATCHDOG();
#ifdef PRINT_BLOCKNOS
printf("Pattern 0x%02x\n", patterns[p]);
printf(" block 0x");
#else
printf(" ");
#endif
/* run pattern across every page in every block */
for (i=0; i<block_count; i++)
{
KICK_WATCHDOG();
#ifdef PRINT_BLOCKNOS
printf("\b\b\b%03X", i);
#else
#ifdef PRINT_SPINNERS
printf ("\b%c", spinners[spinindex++]);
if (spinindex == NUM_SPINNERS)
spinindex = 0;
#endif
#endif
result = do_pattern (i, patterns[p]);
if (result != ERR_OK)
{
printf("\n--- Failed pattern 0x%x at block 0x%x pass 0x%x ",
patterns[p], i, pass);
switch (result)
{
case ERR_BAD_BLOCK:
printf ("- Bad Block Detected\n");
break;
case ERR_ERASE_FAIL:
printf ("- Not erased completely\n");
break;
case ERR_WRITE_FAIL:
printf ("- Write Failed\n");
break;
case ERR_READ_FAIL:
printf ("- Read Failed\n");
break;
case ERR_VERIFY_FAIL:
printf ("- Verify failure\n");
break;
default:
printf ("- Unknown error\n");
break;
}
#ifdef PRINT_BLOCKNOS
printf(" block 0x");
#else
printf(" ");
#endif
} /* if */
} /* for block count */
printf("\n");
} /* for patterns */
} while (1);
#else /* RUN_BAD_FINDER */
printf ("\n\n====== Running bad block finder ====== \n\n");
for (i=0; i<block_count; i++)
{
KICK_WATCHDOG();
if (nand_dev->bad_block_check(nand_dev, i) ==
FS_DEVICE_BAD_BLOCK)
{
printf ("bad block %d\n", i);
}
else
{
// printf ("good block %d\n", i);
}
}
printf ("\n\n====== Done ====== \n\n");
#endif /* !RUN_BAD_FINDER */
return;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?