From owner-svn-src-projects@FreeBSD.ORG Sat Apr 7 05:13:03 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 27FED1065670; Sat, 7 Apr 2012 05:13:03 +0000 (UTC) (envelope-from gber@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 11B9D8FC0A; Sat, 7 Apr 2012 05:13:03 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q375D30G043955; Sat, 7 Apr 2012 05:13:03 GMT (envelope-from gber@svn.freebsd.org) Received: (from gber@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q375D2Ku043946; Sat, 7 Apr 2012 05:13:02 GMT (envelope-from gber@svn.freebsd.org) Message-Id: <201204070513.q375D2Ku043946@svn.freebsd.org> From: Grzegorz Bernacki Date: Sat, 7 Apr 2012 05:13:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r233980 - projects/nand/usr.sbin/nandsim X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Apr 2012 05:13:03 -0000 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 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] +