svn commit: r233980 - projects/nand/usr.sbin/nandsim
Grzegorz Bernacki
gber at FreeBSD.org
Sat Apr 7 05:13:03 UTC 2012
Author: gber
Date: Sat Apr 7 05:13:02 2012
New Revision: 233980
URL: http://svn.freebsd.org/changeset/base/233980
Log:
nandsim: Various fixes
Obtained from: Semihalf
Supported by: FreeBSD Foundation, Juniper Networks
Modified:
projects/nand/usr.sbin/nandsim/Makefile
projects/nand/usr.sbin/nandsim/nandsim.8
projects/nand/usr.sbin/nandsim/nandsim.c
projects/nand/usr.sbin/nandsim/nandsim_cfgparse.c
projects/nand/usr.sbin/nandsim/nandsim_cfgparse.h
projects/nand/usr.sbin/nandsim/nandsim_rcfile.c
projects/nand/usr.sbin/nandsim/nandsim_rcfile.h
projects/nand/usr.sbin/nandsim/sample.conf
Modified: projects/nand/usr.sbin/nandsim/Makefile
==============================================================================
--- projects/nand/usr.sbin/nandsim/Makefile Sat Apr 7 05:04:14 2012 (r233979)
+++ projects/nand/usr.sbin/nandsim/Makefile Sat Apr 7 05:13:02 2012 (r233980)
@@ -1,8 +1,8 @@
+# $FreeBSD$
+
PROG= nandsim
SRCS= nandsim.c nandsim_rcfile.c nandsim_cfgparse.c
BINDIR= /usr/sbin
-MAN=nandsim.8
-
-WARNS?= 3
+MAN= nandsim.8
.include <bsd.prog.mk>
Modified: projects/nand/usr.sbin/nandsim/nandsim.8
==============================================================================
--- projects/nand/usr.sbin/nandsim/nandsim.8 Sat Apr 7 05:04:14 2012 (r233979)
+++ projects/nand/usr.sbin/nandsim/nandsim.8 Sat Apr 7 05:13:02 2012 (r233980)
@@ -27,7 +27,7 @@
.Os
.Sh NAME
.Nm nandsim
-.Nd NAND simulator
+.Nd NAND simulator control program
.Sh SYNOPSIS
.Nm
.Ic status
@@ -211,5 +211,15 @@ gives more verbose output.
Stops simulation of given controller (simulates power-loss). All
commands issues to any chip on this controller are ignored.
.El
-.Sh AUTHORS
-.An Lukasz Wojcik
+.Sh SEE ALSO
+.Xr nand 4 ,
+.Xr nandsim 4
+.Xr nandsim.conf 5
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 10.0 .
+.Sh AUTHOR
+This utility was written by
+.An Lukasz Wojcik .
Modified: projects/nand/usr.sbin/nandsim/nandsim.c
==============================================================================
--- projects/nand/usr.sbin/nandsim/nandsim.c Sat Apr 7 05:04:14 2012 (r233979)
+++ projects/nand/usr.sbin/nandsim/nandsim.c Sat Apr 7 05:13:02 2012 (r233980)
@@ -89,11 +89,11 @@ __FBSDID("$FreeBSD$");
typedef int (commandfunc_t)(int , char **);
-static struct nandsim_command *getcommand(char *arg);
-static int parse_devstring(char *str, int *ctrl, int *cs);
-static void printchip(struct sim_chip *chip, uint8_t verbose);
-static void printctrl(struct sim_ctrl *ctrl);
-static int opendev(int *fd);
+static struct nandsim_command *getcommand(char *);
+static int parse_devstring(char *, int *, int *);
+static void printchip(struct sim_chip *, uint8_t);
+static void printctrl(struct sim_ctrl *);
+static int opendev(int *);
static commandfunc_t cmdstatus;
static commandfunc_t cmdconf;
static commandfunc_t cmdstart;
@@ -108,12 +108,12 @@ static commandfunc_t cmddump;
static commandfunc_t cmdrestore;
static commandfunc_t cmddestroy;
static commandfunc_t cmdhelp;
-static int checkusage(int argc, int argsreqd, char **argv);
-static int is_chip_created(int ctrl_no, int chip_no, int *created);
-static int is_ctrl_created(int ctrl_no, int *created);
-static int is_ctrl_running(int ctrl_no, int *running);
-static int assert_chip_connected(int ctrl_no, int chip_no);
-static int printstats(int ctrlno, int chipno, uint32_t pageno, int cdevd);
+static int checkusage(int, int, char **);
+static int is_chip_created(int, int, int *);
+static int is_ctrl_created(int, int *);
+static int is_ctrl_running(int, int *);
+static int assert_chip_connected(int , int);
+static int printstats(int, int, uint32_t, int);
struct nandsim_command {
const char *cmd_name; /* Command name */
@@ -193,7 +193,7 @@ parse_devstring(char *str, int *ctrl, in
*cs = 0xff;
if (strcmp(str, "--all") == 0 ||
strcmp(str, "-a") == 0) {
- /* if --all or -a is specified, ctl==chip==0xff */
+ /* If --all or -a is specified, ctl==chip==0xff */
debug("CTRL=%d CHIP=%d\n", *ctrl, *cs);
return (0);
}
@@ -237,7 +237,6 @@ static int
opendev(int *fd)
{
- /* Open simulator device. */
*fd = open(SIMDEVICE, O_RDWR);
if (*fd == -1) {
error("Could not open simulator device file (%s)!",
@@ -270,10 +269,10 @@ checkusage(int gargc, int argsreqd, char
if (gargc < argsreqd + 2 || (gargc >= (argsreqd + 2) &&
(strcmp(gargv[1], "--help") == 0 ||
- strcmp(gargv[1], "-h") == 0))) {
+ strcmp(gargv[1], "-h") == 0)))
return (1);
- } else
- return (0);
+
+ return (0);
}
static int
@@ -335,7 +334,7 @@ cmdstatus(int gargc, char **gargv)
}
static int
-cmdconf(int gargc, char **gargv)
+cmdconf(int gargc __unused, char **gargv)
{
int err;
@@ -347,7 +346,7 @@ cmdconf(int gargc, char **gargv)
}
static int
-cmdstart(int gargc, char **gargv)
+cmdstart(int gargc __unused, char **gargv)
{
int chip = 0, ctl = 0, err = 0, fd, running, state;
@@ -384,7 +383,7 @@ cmdstart(int gargc, char **gargv)
}
static int
-cmdstop(int gargc, char **gargv)
+cmdstop(int gargc __unused, char **gargv)
{
int chip = 0, ctl = 0, err = 0, fd, running;
@@ -414,7 +413,7 @@ cmdstop(int gargc, char **gargv)
}
static int
-cmdmod(int gargc, char **gargv)
+cmdmod(int gargc __unused, char **gargv)
{
int chip, ctl, err = 0, fd = -1, i;
struct sim_mod mods;
@@ -434,7 +433,7 @@ cmdmod(int gargc, char **gargv)
err = ioctl(fd, NANDSIM_MODIFY, &mods);
if (err) {
error("simulator parameter %s could not be "
- "modified !", gargv[i]);
+ "modified !", gargv[3]);
close(fd);
return (EX_SOFTWARE);
}
@@ -460,10 +459,10 @@ cmdmod(int gargc, char **gargv)
if (opendev(&fd) != EX_OK)
return (EX_OSFILE);
- /* Findout which flags were passed */
+ /* Find out which flags were passed */
for (i = 3; i < gargc; i++) {
- if (convert_arguint(gargv[i+1], &mods.new_value) != 0)
+ if (convert_arguint(gargv[i + 1], &mods.new_value) != 0)
continue;
if (strcmp(gargv[i], "--prog-time") == 0 ||
@@ -515,7 +514,7 @@ cmdmod(int gargc, char **gargv)
}
static int
-cmderror(int gargc, char **gargv)
+cmderror(int gargc __unused, char **gargv)
{
uint32_t page, column, len, pattern;
int chip = 0, ctl = 0, err = 0, fd;
@@ -536,7 +535,7 @@ cmderror(int gargc, char **gargv)
convert_arguint(gargv[6], &pattern))
return (EX_SOFTWARE);
- if(!assert_chip_connected(ctl, chip))
+ if (!assert_chip_connected(ctl, chip))
return (EX_SOFTWARE);
sim_err.page_num = page;
@@ -594,7 +593,7 @@ cmdbb(int gargc, char **gargv)
bs.ctrl_num = ctl;
bs.chip_num = chip;
- if(!assert_chip_connected(ctl, chip))
+ if (!assert_chip_connected(ctl, chip))
return (EX_SOFTWARE);
if (opencdev(&cdevd, ctl, chip) != EX_OK)
@@ -657,7 +656,7 @@ cmdbb(int gargc, char **gargv)
}
static int
-cmdfreeze(int gargc, char **gargv)
+cmdfreeze(int gargc __unused, char **gargv)
{
int chip = 0, ctl = 0, err = 0, fd, i, start = 0, state, stop = 0;
struct sim_ctrl_chip ctrlchip;
@@ -713,7 +712,7 @@ cmdfreeze(int gargc, char **gargv)
}
static int
-cmdlog(int gargc, char **gargv)
+cmdlog(int gargc __unused, char **gargv)
{
struct sim_log log;
int chip = 0, ctl = 0, err = 0, fd, idx, start = 0, stop = 0;
@@ -765,7 +764,7 @@ cmdlog(int gargc, char **gargv)
}
static int
-cmdstats(int gargc, char **gargv)
+cmdstats(int gargc __unused, char **gargv)
{
int cdevd, chip = 0, ctl = 0, err = 0;
uint32_t pageno = 0;
@@ -799,7 +798,7 @@ cmdstats(int gargc, char **gargv)
}
static int
-cmddump(int gargc, char **gargv)
+cmddump(int gargc __unused, char **gargv)
{
struct sim_dump dump;
struct sim_block_state bs;
@@ -927,7 +926,7 @@ cmddump(int gargc, char **gargv)
}
static int
-cmdrestore(int gargc, char **gargv)
+cmdrestore(int gargc __unused, char **gargv)
{
struct sim_dump dump;
struct sim_block_state bs;
@@ -973,8 +972,7 @@ cmdrestore(int gargc, char **gargv)
cparams.oob_size);
/* Expected dump file size for chip */
- expfilesz = cparams.blocks * (blksz + sizeof(bs)) +
- sizeof(cparams);
+ expfilesz = cparams.blocks * (blksz + sizeof(bs)) + sizeof(cparams);
if (fsize != expfilesz) {
error("File size does not match chip geometry (file size: %d"
@@ -985,7 +983,6 @@ cmdrestore(int gargc, char **gargv)
dumpfd = open(gargv[3], O_RDONLY);
if (dumpfd == -1) {
error("Could not open dump file!");
- free(buf);
return (EX_IOERR);
}
@@ -1070,7 +1067,7 @@ cmdrestore(int gargc, char **gargv)
}
static int
-cmddestroy(int gargc, char **gargv)
+cmddestroy(int gargc __unused, char **gargv)
{
int chip = 0, ctl = 0, err = 0, fd, idx, idx2, state;
int chipstart, chipstop, ctrlstart, ctrlstop;
@@ -1134,7 +1131,7 @@ cmddestroy(int gargc, char **gargv)
ioctl(fd, NANDSIM_DESTROY_CHIP,
&chip_destroy);
}
- /* If chip isnt explicitely specified -- destroy ctrl */
+ /* If chip isn't explicitly specified -- destroy ctrl */
if (chip == 0xff) {
err = ioctl(fd, NANDSIM_DESTROY_CTRL, &idx);
if (err) {
@@ -1182,7 +1179,7 @@ main(int argc, char **argv)
}
static int
-cmdhelp(int gargc, char **gargv)
+cmdhelp(int gargc __unused, char **gargv __unused)
{
struct nandsim_command *opts;
@@ -1365,7 +1362,7 @@ printstats(int ctrlno, int chipno, uint3
if (err) {
error("Could not acquire chip info for chip attached to cs#"
- "%d, ctrl#%d", chipno, ctrlno);
+ "%d, ctrl#%d", chipno, ctrlno);
return (EX_SOFTWARE);
}
Modified: projects/nand/usr.sbin/nandsim/nandsim_cfgparse.c
==============================================================================
--- projects/nand/usr.sbin/nandsim/nandsim_cfgparse.c Sat Apr 7 05:04:14 2012 (r233979)
+++ projects/nand/usr.sbin/nandsim/nandsim_cfgparse.c Sat Apr 7 05:13:02 2012 (r233980)
@@ -122,23 +122,26 @@ static struct nandsim_key nandsim_chip_k
{"width", 1, VALUE_UINT | SIZE_8, (void *)&chip_conf.width, 0},
{"wear_out", 1, VALUE_UINT | SIZE_32, (void *)&chip_conf.wear_level,
0},
+ {"bad_block_map", 0, VALUE_UINTARRAY | SIZE_32,
+ (void *)&chip_conf.bad_block_map, MAX_BAD_BLOCKS},
{NULL, 0, 0, NULL, 0},
};
struct nandsim_section sections[] = {
{"ctrl", (struct nandsim_key *)&nandsim_ctrl_keys},
{"chip", (struct nandsim_key *)&nandsim_chip_keys},
+ {NULL, NULL},
};
static uint8_t logoutputtoint(char *, int *);
-static uint8_t validate_chips(struct sim_chip *chips, int chipcnt,
- struct sim_ctrl *ctrls, int ctrlcnt);
-static uint8_t validate_ctrls(struct sim_ctrl *ctrl, int ctrlcnt);
-static int configure_sim(const char *cfgfilename, struct rcfile *f);
-static int create_ctrls(struct rcfile *f, struct sim_ctrl **ctrls, int *cnt);
-static int create_chips(struct rcfile *f, struct sim_chip **chips, int *cnt);
-static void destroy_ctrls(struct sim_ctrl *ctrls);
-static void destroy_chips(struct sim_chip *chips);
+static uint8_t validate_chips(struct sim_chip *, int, struct sim_ctrl *, int);
+static uint8_t validate_ctrls(struct sim_ctrl *, int);
+static int configure_sim(const char *, struct rcfile *);
+static int create_ctrls(struct rcfile *, struct sim_ctrl **, int *);
+static int create_chips(struct rcfile *, struct sim_chip **, int *);
+static void destroy_ctrls(struct sim_ctrl *);
+static void destroy_chips(struct sim_chip *);
+static int validate_section_config(struct rcfile *, const char *, int);
int
convert_argint(char *arg, int *value)
@@ -335,12 +338,19 @@ create_ctrls(struct rcfile *f, struct si
for (i = 0; i < count; i++) {
bzero((void *)&ctrl_conf, sizeof(ctrl_conf));
+
/*
- * Ecc layout have to end up with 0xffff, so
+ * ECC layout have to end up with 0xffff, so
* we're filling buffer with 0xff. If ecc_layout is
* defined in config file, values will be overriden.
*/
- memset((void *)&ctrl_conf.ecc_layout, 0xff, MAX_ECC_BYTES);
+ memset((void *)&ctrl_conf.ecc_layout, 0xff,
+ sizeof(ctrl_conf.ecc_layout));
+
+ if (validate_section_config(f, "ctrl", i) != 0) {
+ free(ctrlsptr);
+ return (EINVAL);
+ }
if (parse_section(f, "ctrl", i) != 0) {
free(ctrlsptr);
@@ -351,9 +361,9 @@ create_ctrls(struct rcfile *f, struct si
/* Try to create ctrl with config parsed */
debug("NUM=%d\nNUM_CS=%d\nECC=%d\nFILENAME=%s\nECC_LAYOUT[0]"
"=%d\nECC_LAYOUT[1]=%d\n\n",
- ctrlsptr[i].num, ctrlsptr[i].num_cs, ctrlsptr[i].ecc,
- ctrlsptr[i].filename, ctrlsptr[i].ecc_layout[0],
- ctrlsptr[i].ecc_layout[1]);
+ ctrlsptr[i].num, ctrlsptr[i].num_cs, ctrlsptr[i].ecc,
+ ctrlsptr[i].filename, ctrlsptr[i].ecc_layout[0],
+ ctrlsptr[i].ecc_layout[1]);
}
*cnt = count;
*ctrls = ctrlsptr;
@@ -391,6 +401,19 @@ create_chips(struct rcfile *f, struct si
for (i = 0; i < count; i++) {
bzero((void *)&chip_conf, sizeof(chip_conf));
+ /*
+ * Bad block map have to end up with 0xffff, so
+ * we're filling array with 0xff. If bad block map is
+ * defined in config file, values will be overriden.
+ */
+ memset((void *)&chip_conf.bad_block_map, 0xff,
+ sizeof(chip_conf.bad_block_map));
+
+ if (validate_section_config(f, "chip", i) != 0) {
+ free(chipsptr);
+ return (EINVAL);
+ }
+
if (parse_section(f, "chip", i) != 0) {
free(chipsptr);
return (EINVAL);
@@ -404,15 +427,15 @@ create_chips(struct rcfile *f, struct si
"MAN=%s\nCOLADDRCYCLES=%d\nROWADDRCYCLES=%d\nCHWIDTH=%d\n"
"PGS/BLK=%d\nBLK/LUN=%d\nLUNS=%d\nERR_RATIO=%d\n"
"WEARLEVEL=%d\nISWP=%d\n\n\n\n",
- chipsptr[i].num, chipsptr[i].ctrl_num,
- chipsptr[i].device_id, chipsptr[i].manufact_id,
- chipsptr[i].page_size, chipsptr[i].oob_size,
- chipsptr[i].read_time, chipsptr[i].device_model,
- chipsptr[i].manufacturer, chipsptr[i].col_addr_cycles,
- chipsptr[i].row_addr_cycles, chipsptr[i].width,
- chipsptr[i].pgs_per_blk, chipsptr[i].blks_per_lun,
- chipsptr[i].luns, chipsptr[i].error_ratio,
- chipsptr[i].wear_level, chipsptr[i].is_wp);
+ chipsptr[i].num, chipsptr[i].ctrl_num,
+ chipsptr[i].device_id, chipsptr[i].manufact_id,
+ chipsptr[i].page_size, chipsptr[i].oob_size,
+ chipsptr[i].read_time, chipsptr[i].device_model,
+ chipsptr[i].manufacturer, chipsptr[i].col_addr_cycles,
+ chipsptr[i].row_addr_cycles, chipsptr[i].width,
+ chipsptr[i].pgs_per_blk, chipsptr[i].blks_per_lun,
+ chipsptr[i].luns, chipsptr[i].error_ratio,
+ chipsptr[i].wear_level, chipsptr[i].is_wp);
}
*cnt = count;
*chips = chipsptr;
@@ -563,14 +586,14 @@ get_argument_intarray(const char *sect_n
if (getres != 0) {
if (key->mandatory != 0) {
error(MSG_MANDATORYKEYMISSING, key->keyname,
- sect_name);
+ sect_name);
return (EINVAL);
} else
/* Non-mandatory key, not present -- skip */
return (0);
}
cnt = parse_intarray((char *)&strbuf, &intbuf);
- cnt = (cnt <= key->maxlength) ? cnt : key->maxlength - 1;
+ cnt = (cnt <= key->maxlength) ? cnt : key->maxlength;
for (i = 0; i < cnt; i++) {
if (SIZE(key->valuetype) == SIZE_8)
@@ -609,7 +632,7 @@ get_argument_int(const char *sect_name,
} else
/* Non-mandatory key, not present -- skip */
return (0);
- }
+ }
if (SIZE(key->valuetype) == SIZE_8)
*(uint8_t *)(key->field) = (uint8_t)val;
else if (SIZE(key->valuetype) == SIZE_16)
@@ -832,7 +855,7 @@ validate_chips(struct sim_chip *chips, i
if ((chips[chipcnt].read_time < DELAYTIME_MIN ||
chips[chipcnt].read_time > DELAYTIME_MAX) &&
- chips[chipcnt].erase_time != 0) {
+ chips[chipcnt].read_time != 0) {
error("Invalid read time value for chip#%d at "
"ctrl#%d!",
chips[chipcnt].num,
@@ -865,7 +888,6 @@ validate_chips(struct sim_chip *chips, i
static uint8_t
validate_ctrls(struct sim_ctrl *ctrl, int ctrlcnt)
{
-
for (ctrlcnt -= 1; ctrlcnt >= 0; ctrlcnt--) {
if (ctrl[ctrlcnt].num > MAX_SIM_DEV) {
error("Controller no. too high (%d)!!\n",
@@ -877,9 +899,54 @@ validate_ctrls(struct sim_ctrl *ctrl, in
return (EINVAL);
}
if (ctrl[ctrlcnt].ecc != 0 && ctrl[ctrlcnt].ecc != 1) {
- error("ECC is not set to neither 0 nor 1 !\n");
+ error("ECC is set to neither 0 nor 1 !\n");
+ return (EINVAL);
+ }
+ }
+
+ return (0);
+}
+
+static int validate_section_config(struct rcfile *f, const char *sect_name,
+ int sectno)
+{
+ struct nandsim_key *key;
+ struct nandsim_section *sect;
+ char **keys_tbl;
+ int i, match;
+
+ for (match = 0, sect = (struct nandsim_section *)§ions;
+ sect != NULL; sect++) {
+ if (strcmp(sect->name, sect_name) == 0) {
+ match = 1;
+ break;
+ }
+ }
+
+ if (match == 0)
+ return (EINVAL);
+
+ keys_tbl = rc_getkeys(f, sect_name, sectno);
+ if (keys_tbl == NULL)
+ return (ENOMEM);
+
+ for (i = 0; keys_tbl[i] != NULL; i++) {
+ key = sect->keys;
+ match = 0;
+ do {
+ if (strcmp(keys_tbl[i], key->keyname) == 0) {
+ match = 1;
+ break;
+ }
+ } while ((++key)->keyname != NULL);
+
+ if (match == 0) {
+ error("Invalid key in config file: %s\n", keys_tbl[i]);
+ free(keys_tbl);
return (EINVAL);
}
}
+
+ free(keys_tbl);
return (0);
}
Modified: projects/nand/usr.sbin/nandsim/nandsim_cfgparse.h
==============================================================================
--- projects/nand/usr.sbin/nandsim/nandsim_cfgparse.h Sat Apr 7 05:04:14 2012 (r233979)
+++ projects/nand/usr.sbin/nandsim/nandsim_cfgparse.h Sat Apr 7 05:13:02 2012 (r233980)
@@ -77,9 +77,8 @@ struct nandsim_config {
int parse_intarray(char *, int **);
int parse_config(char *, const char *);
int parse_section(struct rcfile *, const char *, int);
-int compare_configs(struct nandsim_config *runningconfig,
- struct nandsim_config *newconfig);
-int convert_argint(char *arg, int *value);
-int convert_arguint(char *arg, unsigned int *value);
+int compare_configs(struct nandsim_config *, struct nandsim_config *);
+int convert_argint(char *, int *);
+int convert_arguint(char *, unsigned int *);
#endif /* _NANDSIM_CONFPARSER_H_ */
Modified: projects/nand/usr.sbin/nandsim/nandsim_rcfile.c
==============================================================================
--- projects/nand/usr.sbin/nandsim/nandsim_rcfile.c Sat Apr 7 05:04:14 2012 (r233979)
+++ projects/nand/usr.sbin/nandsim/nandsim_rcfile.c Sat Apr 7 05:13:02 2012 (r233980)
@@ -80,7 +80,7 @@ rc_open(const char *filename, const char
return ENOMEM;
}
bzero(rcp, sizeof(struct rcfile));
- rcp->rf_name = strdup (filename);
+ rcp->rf_name = strdup(filename);
rcp->rf_f = f;
SLIST_INSERT_HEAD(&pf_head, rcp, rf_next);
rc_parse(rcp);
@@ -237,7 +237,7 @@ rc_parse(struct rcfile *rcp)
}
}
if (state == stSkipToEOL || next == last) {/* ignore long lines */
- if (c == '\n'){
+ if (c == '\n') {
state = stNewLine;
next = buf;
}
@@ -256,7 +256,7 @@ rc_parse(struct rcfile *rcp)
if (state == stGetKey) {
if (c == ' ' || c == '\t')/* side effect: 'key name='*/
continue; /* become 'keyname=' */
- if (c == '\n') { /* silently ignore ... */
+ if (c == '\n') { /* silently ignore ... */
state = stNewLine;
continue;
}
@@ -266,7 +266,8 @@ rc_parse(struct rcfile *rcp)
}
*next = 0;
if (rsp == NULL) {
- fprintf(stderr, "Key '%s' defined before section\n", buf);
+ fprintf(stderr, "Key '%s' defined before "
+ "section\n", buf);
state = stSkipToEOL;
continue;
}
@@ -277,7 +278,8 @@ rc_parse(struct rcfile *rcp)
}
/* only stGetValue left */
if (state != stGetValue) {
- fprintf(stderr, "Well, I can't parse file '%s'\n",rcp->rf_name);
+ fprintf(stderr, "Well, I can't parse file "
+ "'%s'\n",rcp->rf_name);
state = stSkipToEOL;
}
if (c != '\n') {
@@ -348,7 +350,8 @@ rc_getint(struct rcfile *rcp, const char
errno = 0;
*value = strtol(rkp->rk_value,NULL,0);
if (errno) {
- fprintf(stderr, "invalid int value '%s' for key '%s' in section '%s'\n",rkp->rk_value,key,section);
+ fprintf(stderr, "invalid int value '%s' for key '%s' in "
+ "section '%s'\n",rkp->rk_value,key,section);
return (errno);
}
return (0);
@@ -386,7 +389,8 @@ rc_getbool(struct rcfile *rcp, const cha
*value = 1;
return (0);
}
- fprintf(stderr, "invalid boolean value '%s' for key '%s' in section '%s' \n",p, key, section);
+ fprintf(stderr, "invalid boolean value '%s' for key '%s' in section "
+ "'%s' \n",p, key, section);
return (EINVAL);
}
@@ -403,7 +407,33 @@ int rc_getsectionscount(struct rcfile *f
p = rc_findsect(f, sectname, count);
}
return (count);
- }
- else
+ } else
return (0);
}
+
+char **
+rc_getkeys(struct rcfile *rcp, const char *sectname, int sect_id)
+{
+ struct rcsection *rsp;
+ struct rckey *p;
+ char **names_tbl;
+ int i = 0, count = 0;
+
+ rsp = rc_findsect(rcp, sectname, sect_id);
+ if (rsp == NULL)
+ return (NULL);
+
+ SLIST_FOREACH(p, &rsp->rs_keys, rk_next)
+ count++;
+
+ names_tbl = malloc(sizeof(char *) * (count + 1));
+ if (names_tbl == NULL)
+ return (NULL);
+
+ SLIST_FOREACH(p, &rsp->rs_keys, rk_next)
+ names_tbl[i++] = p->rk_name;
+
+ names_tbl[i] = NULL;
+ return (names_tbl);
+}
+
Modified: projects/nand/usr.sbin/nandsim/nandsim_rcfile.h
==============================================================================
--- projects/nand/usr.sbin/nandsim/nandsim_rcfile.h Sat Apr 7 05:04:14 2012 (r233979)
+++ projects/nand/usr.sbin/nandsim/nandsim_rcfile.h Sat Apr 7 05:13:02 2012 (r233980)
@@ -45,7 +45,6 @@ struct rcsection {
SLIST_HEAD(rckey_head,rckey) rs_keys; /* key list */
char *rs_name; /* section name */
int rs_id; /* allow few same named */
-
};
struct rcfile {
@@ -64,5 +63,6 @@ int rc_getstring(struct rcfile *, const
int rc_getint(struct rcfile *, const char *, int, const char *, int *);
int rc_getbool(struct rcfile *, const char *, int, const char *, int *);
int rc_getsectionscount(struct rcfile *, const char *);
+char **rc_getkeys(struct rcfile *, const char *, int);
#endif /* _SIMRC_H_ */
Modified: projects/nand/usr.sbin/nandsim/sample.conf
==============================================================================
--- projects/nand/usr.sbin/nandsim/sample.conf Sat Apr 7 05:04:14 2012 (r233979)
+++ projects/nand/usr.sbin/nandsim/sample.conf Sat Apr 7 05:13:02 2012 (r233980)
@@ -72,7 +72,7 @@ ecc=on
ecc_layout=[0-53]
# Absolute path to the log file for this controller.
-log_filename=/var/log/nandsim-ctl0.log
+#log_filename=/var/log/nandsim-ctl0.log
#############################################################################
@@ -129,17 +129,17 @@ column_addr_cycle=2
row_addr_cycle=3
# program_time= (in us)
-program_time=700
+program_time=0
# erase_time= (in us)
-erase_time=2000
+erase_time=0
# read_time= (in us)
-read_time=600
+read_time=0
# ccs_time= (in us)
-ccs_time=200
+#ccs_time=200
# Simulate write-protect on the chip.
# write_protect=[yes|no]
-write_protect=no
+#write_protect=no
# Blocks wear-out threshold. Each block has a counter of program-erase cycles;
# when this counter reaches 'wear_out' value a given block is treated as a bad
@@ -158,10 +158,17 @@ wear_out=50000
# such problems).
#
# error_ratio=0..1000000
-error_ratio=50
+#error_ratio=50
# Chip data bus width. All chips connected to the same controller must have
# the same bus width.
#
# width=[8|16]
width=8
+
+# Bad block map. NANDsim emulates bad block behavior upon accessing a block
+# with number from the specified list.
+#
+# bad_block_map=[bad_block1, bad_block2-bad_block3, ..bad_blockn]
+bad_block_map=[100-200]
+
More information about the svn-src-projects
mailing list