static int cmdstats(int gargc __unused, char **gargv) { int cdevd, chip = 0, ctl = 0, err = 0; uint32_t pageno = 0; err = parse_devstring(gargv[2], &ctl, &chip); if (err) return (EX_USAGE); if (chip == 0xff) { error(MSG_CTRLCHIPNEEDED); return (EX_USAGE); } if (convert_arguint(gargv[3], &pageno) != 0) return (EX_USAGE); if (!assert_chip_connected(ctl, chip)) return (EX_SOFTWARE); if (opencdev(&cdevd, ctl, chip) != EX_OK) return (EX_OSFILE); err = printstats(ctl, chip, pageno, cdevd); if (err) { close(cdevd); return (EX_SOFTWARE); } close(cdevd); return (EX_OK); }
static int cmdstop(int gargc __unused, char **gargv) { int chip = 0, ctl = 0, err = 0, fd, running; err = parse_devstring(gargv[2], &ctl, &chip); if (err) return (EX_USAGE); err = is_ctrl_running(ctl, &running); if (err) return (EX_SOFTWARE); if (!running) { error(MSG_NOTRUNNING, ctl); } else { if (opendev(&fd) != EX_OK) return (EX_OSFILE); err = ioctl(fd, NANDSIM_STOP_CTRL, &ctl); close(fd); if (err) { error("Cannot stop controller#%d", ctl); err = EX_SOFTWARE; } } return (err); }
static int cmdstatus(int gargc, char **gargv) { int chip = 0, ctl = 0, err = 0, fd, idx, idx2, start, stop; uint8_t verbose = 0; struct sim_ctrl ctrlconf; struct sim_chip chipconf; err = parse_devstring(gargv[2], &ctl, &chip); if (err) { return (EX_USAGE); } else if (ctl == 0xff) { /* Every controller */ start = 0; stop = MAX_SIM_DEV-1; } else { /* Specified controller only */ start = ctl; stop = ctl; } if (opendev(&fd) != EX_OK) return (EX_OSFILE); for (idx = 0; idx < gargc; idx ++) if (strcmp(gargv[idx], "-v") == 0 || strcmp(gargv[idx], "--verbose") == 0) verbose = 1; for (idx = start; idx <= stop; idx++) { ctrlconf.num = idx; err = ioctl(fd, NANDSIM_STATUS_CTRL, &ctrlconf); if (err) { err = EX_SOFTWARE; error(MSG_STATUSACQCTRL, idx); continue; } printctrl(&ctrlconf); for (idx2 = 0; idx2 < MAX_CTRL_CS; idx2++) { chipconf.num = idx2; chipconf.ctrl_num = idx; err = ioctl(fd, NANDSIM_STATUS_CHIP, &chipconf); if (err) { err = EX_SOFTWARE; error(MSG_STATUSACQCTRL, idx); continue; } printchip(&chipconf, verbose); } } close(fd); return (err); }
static int 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; err = parse_devstring(gargv[2], &ctl, &chip); if (err) return (EX_USAGE); if (ctl == 0xff) { error("You have to specify at least controller number"); return (EX_USAGE); } if (ctl != 0xff && chip == 0xff) { start = 0; stop = MAX_CTRL_CS - 1; } else { start = chip; stop = chip; } ctrlchip.ctrl_num = ctl; err = is_ctrl_running(ctl, &state); if (err) return (EX_SOFTWARE); if (state == 0) { error(MSG_NOTRUNNING, ctl); return (EX_SOFTWARE); } if (opendev(&fd) != EX_OK) return (EX_OSFILE); for (i = start; i <= stop; i++) { err = is_chip_created(ctl, i, &state); if (err) return (EX_SOFTWARE); else if (state == 0) { continue; } ctrlchip.chip_num = i; err = ioctl(fd, NANDSIM_FREEZE, &ctrlchip); if (err) { error("Could not freeze ctrl#%d chip#%d", ctl, i); close(fd); return (EX_SOFTWARE); } } close(fd); return (EX_OK); }
static int cmdlog(int gargc __unused, char **gargv) { struct sim_log log; int chip = 0, ctl = 0, err = 0, fd, idx, start = 0, stop = 0; char *logbuf; err = parse_devstring(gargv[2], &ctl, &chip); if (err) return (EX_USAGE); logbuf = (char *)malloc(sizeof(char) * NANDSIM_RAM_LOG_SIZE); if (logbuf == NULL) { error("Not enough memory to create log buffer"); return (EX_SOFTWARE); } memset(logbuf, 0, NANDSIM_RAM_LOG_SIZE); log.log = logbuf; log.len = NANDSIM_RAM_LOG_SIZE; if (ctl == 0xff) { start = 0; stop = MAX_SIM_DEV-1; } else { start = ctl; stop = ctl; } if (opendev(&fd) != EX_OK) { free(logbuf); return (EX_OSFILE); } /* Print logs for selected controller(s) */ for (idx = start; idx <= stop; idx++) { log.ctrl_num = idx; err = ioctl(fd, NANDSIM_PRINT_LOG, &log); if (err) { error("Could not get log for controller %d!", idx); continue; } printf("Logs for controller#%d:\n%s\n", idx, logbuf); } free(logbuf); close(fd); return (EX_OK); }
static int cmderror(int gargc __unused, char **gargv) { uint32_t page, column, len, pattern; int chip = 0, ctl = 0, err = 0, fd; struct sim_error sim_err; err = parse_devstring(gargv[2], &ctl, &chip); if (err) return (EX_USAGE); if (chip == 0xff) { error(MSG_CTRLCHIPNEEDED); return (EX_USAGE); } if (convert_arguint(gargv[3], &page) || convert_arguint(gargv[4], &column) || convert_arguint(gargv[5], &len) || convert_arguint(gargv[6], &pattern)) return (EX_SOFTWARE); if (!assert_chip_connected(ctl, chip)) return (EX_SOFTWARE); sim_err.page_num = page; sim_err.column = column; sim_err.len = len; sim_err.pattern = pattern; sim_err.ctrl_num = ctl; sim_err.chip_num = chip; if (opendev(&fd) != EX_OK) return (EX_OSFILE); err = ioctl(fd, NANDSIM_INJECT_ERROR, &sim_err); close(fd); if (err) { error("Could not inject error !"); return (EX_SOFTWARE); } return (EX_OK); }
static int cmdstart(int gargc __unused, char **gargv) { int chip = 0, ctl = 0, err = 0, fd, running, state; err = parse_devstring(gargv[2], &ctl, &chip); if (err) return (EX_USAGE); err = is_ctrl_created(ctl, &state); if (err) { return (EX_SOFTWARE); } else if (state == 0) { error(MSG_NOCTRL, ctl); return (EX_SOFTWARE); } err = is_ctrl_running(ctl, &running); if (err) return (EX_SOFTWARE); if (running) { warn(MSG_RUNNING, ctl); } else { if (opendev(&fd) != EX_OK) return (EX_OSFILE); err = ioctl(fd, NANDSIM_START_CTRL, &ctl); close(fd); if (err) { error("Cannot start controller#%d", ctl); err = EX_SOFTWARE; } } return (err); }
static int cmdrestore(int gargc __unused, char **gargv) { struct sim_dump dump; struct sim_block_state bs; struct stat filestat; int chip = 0, ctl = 0, err = 0, fd, dumpfd = -1; uint32_t blkidx, blksz, fsize = 0, expfilesz; void *buf; struct chip_param_io cparams, dumpcparams; err = parse_devstring(gargv[2], &ctl, &chip); if (err) return (EX_USAGE); else if (ctl == 0xff) { error(MSG_CTRLCHIPNEEDED); return (EX_USAGE); } if (!assert_chip_connected(ctl, chip)) return (EX_SOFTWARE); /* Get chip geometry */ if (opencdev(&fd, ctl, chip) != EX_OK) return (EX_OSFILE); err = ioctl(fd, NAND_IO_GET_CHIP_PARAM, &cparams); if (err) { error("Cannot get parameters for chip %d:%d", ctl, chip); close(fd); return (err); } close(fd); /* Obtain dump file size */ errno = 0; if (stat(gargv[3], &filestat) != 0) { error("Could not acquire file size! : %s", strerror(errno)); return (EX_IOERR); } fsize = filestat.st_size; blksz = cparams.pages_per_block * (cparams.page_size + cparams.oob_size); /* Expected dump file size for chip */ expfilesz = cparams.blocks * (blksz + sizeof(bs)) + sizeof(cparams); if (fsize != expfilesz) { error("File size does not match chip geometry (file size: %d" ", dump size: %d)", fsize, expfilesz); return (EX_SOFTWARE); } dumpfd = open(gargv[3], O_RDONLY); if (dumpfd == -1) { error("Could not open dump file!"); return (EX_IOERR); } /* Read chip params saved in dumpfile */ read(dumpfd, &dumpcparams, sizeof(dumpcparams)); /* XXX */ if (bcmp(&dumpcparams, &cparams, sizeof(cparams)) != 0) { error("Supplied dump is created for a chip with different " "chip configuration!"); close(dumpfd); return (EX_SOFTWARE); } if (opendev(&fd) != EX_OK) { close(dumpfd); return (EX_OSFILE); } buf = malloc(blksz); if (buf == NULL) { error("Could not allocate memory for block buffer"); close(dumpfd); close(fd); return (EX_SOFTWARE); } dump.ctrl_num = ctl; dump.chip_num = chip; dump.data = buf; /* Restore block states and wearouts */ for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { dump.block_num = blkidx; if (read(dumpfd, &bs, sizeof(bs)) != sizeof(bs)) { error("Error reading dumpfile"); close(dumpfd); close(fd); free(buf); return (EX_SOFTWARE); } bs.ctrl_num = ctl; bs.chip_num = chip; debug("BLKIDX=%d BLOCKS=%d CTRL=%d CHIP=%d STATE=%d\n" "WEAROUT=%d BS.CTRL_NUM=%d BS.CHIP_NUM=%d\n", blkidx, cparams.blocks, dump.ctrl_num, dump.chip_num, bs.state, bs.wearout, bs.ctrl_num, bs.chip_num); err = ioctl(fd, NANDSIM_SET_BLOCK_STATE, &bs); if (err) { error("Could not set bad block(%d) for " "controller: %d, chip: %d!", blkidx, ctl, chip); close(dumpfd); close(fd); free(buf); return (EX_SOFTWARE); } } /* Restore data */ for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { errno = 0; dump.len = read(dumpfd, buf, blksz); if (errno) { error("Failed to read block#%d from dumpfile.", blkidx); err = EX_SOFTWARE; break; } dump.block_num = blkidx; err = ioctl(fd, NANDSIM_RESTORE, &dump); if (err) { error("Could not restore block#%d of ctrl#%d chip#%d" ": %s", blkidx, ctl, chip, strerror(errno)); err = EX_SOFTWARE; break; } } free(buf); close(dumpfd); close(fd); return (err); }
static int cmddump(int gargc __unused, char **gargv) { struct sim_dump dump; struct sim_block_state bs; struct chip_param_io cparams; int chip = 0, ctl = 0, err = EX_OK, fd, dumpfd; uint32_t blkidx, bwritten = 0, totalwritten = 0; void *buf; err = parse_devstring(gargv[2], &ctl, &chip); if (err) return (EX_USAGE); if (chip == 0xff || ctl == 0xff) { error(MSG_CTRLCHIPNEEDED); return (EX_USAGE); } if (!assert_chip_connected(ctl, chip)) return (EX_SOFTWARE); if (opencdev(&fd, ctl, chip) != EX_OK) return (EX_OSFILE); err = ioctl(fd, NAND_IO_GET_CHIP_PARAM, &cparams); if (err) { error("Cannot get parameters for chip %d:%d", ctl, chip); close(fd); return (EX_SOFTWARE); } close(fd); dump.ctrl_num = ctl; dump.chip_num = chip; dump.len = cparams.pages_per_block * (cparams.page_size + cparams.oob_size); buf = malloc(dump.len); if (buf == NULL) { error("Could not allocate memory!"); return (EX_SOFTWARE); } dump.data = buf; errno = 0; dumpfd = open(gargv[3], O_WRONLY | O_CREAT, 0666); if (dumpfd == -1) { error("Cannot create dump file."); free(buf); return (EX_SOFTWARE); } if (opendev(&fd)) { close(dumpfd); free(buf); return (EX_SOFTWARE); } bs.ctrl_num = ctl; bs.chip_num = chip; /* First uint32_t in file shall contain block count */ if (write(dumpfd, &cparams, sizeof(cparams)) < (int)sizeof(cparams)) { error("Error writing to dumpfile!"); close(fd); close(dumpfd); free(buf); return (EX_SOFTWARE); } /* * First loop acquires blocks states and writes them to * the dump file. */ for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { bs.block_num = blkidx; err = ioctl(fd, NANDSIM_GET_BLOCK_STATE, &bs); if (err) { error("Could not get bad block(%d) for " "controller (%d)!", blkidx, ctl); close(fd); close(dumpfd); free(buf); return (EX_SOFTWARE); } bwritten = write(dumpfd, &bs, sizeof(bs)); if (bwritten != sizeof(bs)) { error("Error writing to dumpfile"); close(fd); close(dumpfd); free(buf); return (EX_SOFTWARE); } } /* Second loop dumps the data */ for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { debug("Block#%d...", blkidx); dump.block_num = blkidx; err = ioctl(fd, NANDSIM_DUMP, &dump); if (err) { error("Could not dump ctrl#%d chip#%d " "block#%d", ctl, chip, blkidx); err = EX_SOFTWARE; break; } bwritten = write(dumpfd, dump.data, dump.len); if (bwritten != dump.len) { error("Error writing to dumpfile"); err = EX_SOFTWARE; break; } debug("OK!\n"); totalwritten += bwritten; } printf("%d out of %d B written.\n", totalwritten, dump.len * blkidx); close(fd); close(dumpfd); free(buf); return (err); }
static int cmdbb(int gargc, char **gargv) { struct sim_block_state bs; struct chip_param_io cparams; uint32_t blkidx; int c, cdevd, chip = 0, ctl = 0, err = 0, fd, idx; uint8_t flagL = 0, flagU = 0; int *badblocks = NULL; /* Check for --list/-L or --unmark/-U flags */ for (idx = 3; idx < gargc; idx++) { if (strcmp(gargv[idx], "--list") == 0 || strcmp(gargv[idx], "-L") == 0) flagL = idx; if (strcmp(gargv[idx], "--unmark") == 0 || strcmp(gargv[idx], "-U") == 0) flagU = idx; } if (flagL == 2 || flagU == 2 || flagU == 3) return (EX_USAGE); err = parse_devstring(gargv[2], &ctl, &chip); if (err) { return (EX_USAGE); } if (chip == 0xff || ctl == 0xff) { error(MSG_CTRLCHIPNEEDED); return (EX_USAGE); } bs.ctrl_num = ctl; bs.chip_num = chip; if (!assert_chip_connected(ctl, chip)) return (EX_SOFTWARE); if (opencdev(&cdevd, ctl, chip) != EX_OK) return (EX_OSFILE); err = ioctl(cdevd, NAND_IO_GET_CHIP_PARAM, &cparams); if (err) return (EX_SOFTWARE); close(cdevd); bs.ctrl_num = ctl; bs.chip_num = chip; if (opendev(&fd) != EX_OK) return (EX_OSFILE); if (flagL != 3) { /* * Flag -L was specified either after blocklist or was not * specified at all. */ c = parse_intarray(gargv[3], &badblocks); for (idx = 0; idx < c; idx++) { bs.block_num = badblocks[idx]; /* Do not change wearout */ bs.wearout = -1; bs.state = (flagU == 0) ? NANDSIM_BAD_BLOCK : NANDSIM_GOOD_BLOCK; err = ioctl(fd, NANDSIM_SET_BLOCK_STATE, &bs); if (err) { error("Could not set bad block(%d) for " "controller (%d)!", badblocks[idx], ctl); err = EX_SOFTWARE; break; } } } if (flagL != 0) { /* If flag -L was specified (anywhere) */ for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { bs.block_num = blkidx; /* Do not change the wearout */ bs.wearout = -1; err = ioctl(fd, NANDSIM_GET_BLOCK_STATE, &bs); if (err) { error("Could not acquire block state"); err = EX_SOFTWARE; continue; } printf("Block#%d: wear count: %d %s\n", blkidx, bs.wearout, (bs.state == NANDSIM_BAD_BLOCK) ? "BAD":"GOOD"); } } close(fd); return (err); }
static int cmdmod(int gargc __unused, char **gargv) { int chip, ctl, err = 0, fd = -1, i; struct sim_mod mods; if (gargc >= 4) { if (strcmp(gargv[2], "--loglevel") == 0 || strcmp(gargv[2], "-l") == 0) { /* Set loglevel (ctrl:chip pair independant) */ mods.field = SIM_MOD_LOG_LEVEL; if (convert_arguint(gargv[3], &mods.new_value) != 0) return (EX_SOFTWARE); if (opendev(&fd) != EX_OK) return (EX_OSFILE); err = ioctl(fd, NANDSIM_MODIFY, &mods); if (err) { error("simulator parameter %s could not be " "modified !", gargv[3]); close(fd); return (EX_SOFTWARE); } debug("request : loglevel = %d\n", mods.new_value); close(fd); return (EX_OK); } } err = parse_devstring(gargv[2], &ctl, &chip); if (err) return (EX_USAGE); else if (chip == 0xff) { error(MSG_CTRLCHIPNEEDED); return (EX_USAGE); } if (!assert_chip_connected(ctl, chip)) return (EX_SOFTWARE); if (opendev(&fd) != EX_OK) return (EX_OSFILE); /* Find out which flags were passed */ for (i = 3; i < gargc; i++) { if (convert_arguint(gargv[i + 1], &mods.new_value) != 0) continue; if (strcmp(gargv[i], "--prog-time") == 0 || strcmp(gargv[i], "-p") == 0) { mods.field = SIM_MOD_PROG_TIME; debug("request : progtime = %d\n", mods.new_value); } else if (strcmp(gargv[i], "--erase-time") == 0 || strcmp(gargv[i], "-e") == 0) { mods.field = SIM_MOD_ERASE_TIME; debug("request : eraseime = %d\n", mods.new_value); } else if (strcmp(gargv[i], "--read-time") == 0 || strcmp(gargv[i], "-r") == 0) { mods.field = SIM_MOD_READ_TIME; debug("request : read_time = %d\n", mods.new_value); } else if (strcmp(gargv[i], "--error-ratio") == 0 || strcmp(gargv[i], "-E") == 0) { mods.field = SIM_MOD_ERROR_RATIO; debug("request : error_ratio = %d\n", mods.new_value); } else { /* Flag not recognized, or nothing specified. */ error("Unrecognized flag:%s\n", gargv[i]); if (fd >= 0) close(fd); return (EX_USAGE); } mods.chip_num = chip; mods.ctrl_num = ctl; /* Call appropriate ioctl */ err = ioctl(fd, NANDSIM_MODIFY, &mods); if (err) { error("simulator parameter %s could not be modified! ", gargv[i]); continue; } i++; } close(fd); return (EX_OK); }
static int cmddestroy(int gargc __unused, char **gargv) { int chip = 0, ctl = 0, err = 0, fd, idx, idx2, state; int chipstart, chipstop, ctrlstart, ctrlstop; struct sim_chip_destroy chip_destroy; err = parse_devstring(gargv[2], &ctl, &chip); if (err) return (EX_USAGE); if (ctl == 0xff) { /* Every chip at every controller */ ctrlstart = chipstart = 0; ctrlstop = MAX_SIM_DEV - 1; chipstop = MAX_CTRL_CS - 1; } else { ctrlstart = ctrlstop = ctl; if (chip == 0xff) { /* Every chip at selected controller */ chipstart = 0; chipstop = MAX_CTRL_CS - 1; } else /* Selected chip at selected controller */ chipstart = chipstop = chip; } debug("CTRLSTART=%d CTRLSTOP=%d CHIPSTART=%d CHIPSTOP=%d\n", ctrlstart, ctrlstop, chipstart, chipstop); for (idx = ctrlstart; idx <= ctrlstop; idx++) { err = is_ctrl_created(idx, &state); if (err) { error("Could not acquire ctrl#%d state. Cannot " "destroy controller.", idx); return (EX_SOFTWARE); } if (state == 0) { continue; } err = is_ctrl_running(idx, &state); if (err) { error(MSG_STATUSACQCTRL, idx); return (EX_SOFTWARE); } if (state != 0) { error(MSG_RUNNING, ctl); return (EX_SOFTWARE); } if (opendev(&fd) != EX_OK) return (EX_OSFILE); for (idx2 = chipstart; idx2 <= chipstop; idx2++) { err = is_chip_created(idx, idx2, &state); if (err) { error(MSG_STATUSACQCTRLCHIP, idx2, idx); continue; } if (state == 0) /* There is no such chip running */ continue; chip_destroy.ctrl_num = idx; chip_destroy.chip_num = idx2; ioctl(fd, NANDSIM_DESTROY_CHIP, &chip_destroy); } /* If chip isn't explicitly specified -- destroy ctrl */ if (chip == 0xff) { err = ioctl(fd, NANDSIM_DESTROY_CTRL, &idx); if (err) { error("Could not destroy ctrl#%d", idx); continue; } } close(fd); } return (err); }
static void show_dev_detail(void) { struct sr_dev *dev; const struct sr_hwcap_option *hwo; const struct sr_samplerates *samplerates; struct sr_rational *rationals; uint64_t *integers; const int *hwcaps; int cap, i; char *s, *title; const char *charopts, **stropts; dev = parse_devstring(opt_dev); if (!dev) { printf("No such device. Use -D to list all devices.\n"); return; } print_dev_line(dev); if (sr_dev_info_get(dev, SR_DI_TRIGGER_TYPES, (const void **)&charopts) == SR_OK) { printf("Supported triggers: "); while (*charopts) { printf("%c ", *charopts); charopts++; } printf("\n"); } title = "Supported options:\n"; hwcaps = dev->driver->hwcap_get_all(); for (cap = 0; hwcaps[cap]; cap++) { if (!(hwo = sr_hw_hwcap_get(hwcaps[cap]))) continue; if (title) { printf("%s", title); title = NULL; } if (hwo->hwcap == SR_HWCAP_PATTERN_MODE) { /* Pattern generator modes */ printf(" %s", hwo->shortname); if (sr_dev_info_get(dev, SR_DI_PATTERNS, (const void **)&stropts) == SR_OK) { printf(" - supported patterns:\n"); for (i = 0; stropts[i]; i++) printf(" %s\n", stropts[i]); } else { printf("\n"); } } else if (hwo->hwcap == SR_HWCAP_SAMPLERATE) { /* Supported samplerates */ printf(" %s", hwo->shortname); if (sr_dev_info_get(dev, SR_DI_SAMPLERATES, (const void **)&samplerates) != SR_OK) { printf("\n"); continue; } if (samplerates->step) { /* low */ if (!(s = sr_samplerate_string(samplerates->low))) continue; printf(" (%s", s); g_free(s); /* high */ if (!(s = sr_samplerate_string(samplerates->high))) continue; printf(" - %s", s); g_free(s); /* step */ if (!(s = sr_samplerate_string(samplerates->step))) continue; printf(" in steps of %s)\n", s); g_free(s); } else { printf(" - supported samplerates:\n"); for (i = 0; samplerates->list[i]; i++) printf(" %s\n", sr_samplerate_string(samplerates->list[i])); } } else if (hwo->hwcap == SR_HWCAP_BUFFERSIZE) { /* Supported buffer sizes */ printf(" %s", hwo->shortname); if (sr_dev_info_get(dev, SR_DI_BUFFERSIZES, (const void **)&integers) != SR_OK) { printf("\n"); continue; } printf(" - supported buffer sizes:\n"); for (i = 0; integers[i]; i++) printf(" %"PRIu64"\n", integers[i]); } else if (hwo->hwcap == SR_HWCAP_TIMEBASE) { /* Supported time bases */ printf(" %s", hwo->shortname); if (sr_dev_info_get(dev, SR_DI_TIMEBASES, (const void **)&rationals) != SR_OK) { printf("\n"); continue; } printf(" - supported time bases:\n"); for (i = 0; rationals[i].p && rationals[i].q; i++) printf(" %s\n", sr_period_string( rationals[i].p * rationals[i].q)); } else if (hwo->hwcap == SR_HWCAP_TRIGGER_SOURCE) { /* Supported trigger sources */ printf(" %s", hwo->shortname); if (sr_dev_info_get(dev, SR_DI_TRIGGER_SOURCES, (const void **)&stropts) != SR_OK) { printf("\n"); continue; } printf(" - supported trigger sources:\n"); for (i = 0; stropts[i]; i++) printf(" %s\n", stropts[i]); } else if (hwo->hwcap == SR_HWCAP_FILTER) { /* Supported trigger sources */ printf(" %s", hwo->shortname); if (sr_dev_info_get(dev, SR_DI_FILTERS, (const void **)&stropts) != SR_OK) { printf("\n"); continue; } printf(" - supported filter targets:\n"); for (i = 0; stropts[i]; i++) printf(" %s\n", stropts[i]); } else if (hwo->hwcap == SR_HWCAP_VDIV) { /* Supported volts/div values */ printf(" %s", hwo->shortname); if (sr_dev_info_get(dev, SR_DI_VDIVS, (const void **)&rationals) != SR_OK) { printf("\n"); continue; } printf(" - supported volts/div:\n"); for (i = 0; rationals[i].p && rationals[i].q; i++) printf(" %s\n", sr_voltage_string( &rationals[i])); } else if (hwo->hwcap == SR_HWCAP_COUPLING) { /* Supported coupling settings */ printf(" %s", hwo->shortname); if (sr_dev_info_get(dev, SR_DI_COUPLING, (const void **)&stropts) != SR_OK) { printf("\n"); continue; } printf(" - supported coupling options:\n"); for (i = 0; stropts[i]; i++) printf(" %s\n", stropts[i]); } else { /* Everything else */ printf(" %s\n", hwo->shortname); } } }
static void run_session(void) { struct sr_dev *dev; GHashTable *devargs; int num_devs, max_probes, i; uint64_t time_msec; char **probelist, *devspec; devargs = NULL; if (opt_dev) { devargs = parse_generic_arg(opt_dev); devspec = g_hash_table_lookup(devargs, "sigrok_key"); dev = parse_devstring(devspec); if (!dev) { g_critical("Device not found."); return; } g_hash_table_remove(devargs, "sigrok_key"); } else { num_devs = num_real_devs(); if (num_devs == 1) { /* No device specified, but there is only one. */ devargs = NULL; dev = parse_devstring("0"); } else if (num_devs == 0) { g_critical("No devices found."); return; } else { g_critical("%d devices found, please select one.", num_devs); return; } } sr_session_new(); sr_session_datafeed_callback_add(datafeed_in); if (sr_session_dev_add(dev) != SR_OK) { g_critical("Failed to use device."); sr_session_destroy(); return; } if (devargs) { if (set_dev_options(dev, devargs) != SR_OK) { sr_session_destroy(); return; } g_hash_table_destroy(devargs); } if (select_probes(dev) != SR_OK) return; if (opt_continuous) { if (!sr_driver_hwcap_exists(dev->driver, SR_HWCAP_CONTINUOUS)) { g_critical("This device does not support continuous sampling."); sr_session_destroy(); return; } } if (opt_triggers) { probelist = sr_parse_triggerstring(dev, opt_triggers); if (!probelist) { sr_session_destroy(); return; } max_probes = g_slist_length(dev->probes); for (i = 0; i < max_probes; i++) { if (probelist[i]) { sr_dev_trigger_set(dev, i + 1, probelist[i]); g_free(probelist[i]); } } g_free(probelist); } if (opt_time) { time_msec = sr_parse_timestring(opt_time); if (time_msec == 0) { g_critical("Invalid time '%s'", opt_time); sr_session_destroy(); return; } if (sr_driver_hwcap_exists(dev->driver, SR_HWCAP_LIMIT_MSEC)) { if (dev->driver->dev_config_set(dev->driver_index, SR_HWCAP_LIMIT_MSEC, &time_msec) != SR_OK) { g_critical("Failed to configure time limit."); sr_session_destroy(); return; } } else { /* time limit set, but device doesn't support this... * convert to samples based on the samplerate. */ limit_samples = 0; if (sr_dev_has_hwcap(dev, SR_HWCAP_SAMPLERATE)) { const uint64_t *samplerate; sr_dev_info_get(dev, SR_DI_CUR_SAMPLERATE, (const void **)&samplerate); limit_samples = (*samplerate) * time_msec / (uint64_t)1000; } if (limit_samples == 0) { g_critical("Not enough time at this samplerate."); sr_session_destroy(); return; } if (dev->driver->dev_config_set(dev->driver_index, SR_HWCAP_LIMIT_SAMPLES, &limit_samples) != SR_OK) { g_critical("Failed to configure time-based sample limit."); sr_session_destroy(); return; } } } if (opt_samples) { if ((sr_parse_sizestring(opt_samples, &limit_samples) != SR_OK) || (dev->driver->dev_config_set(dev->driver_index, SR_HWCAP_LIMIT_SAMPLES, &limit_samples) != SR_OK)) { g_critical("Failed to configure sample limit."); sr_session_destroy(); return; } } if (opt_frames) { if ((sr_parse_sizestring(opt_frames, &limit_frames) != SR_OK) || (dev->driver->dev_config_set(dev->driver_index, SR_HWCAP_LIMIT_FRAMES, &limit_frames) != SR_OK)) { printf("Failed to configure frame limit.\n"); sr_session_destroy(); return; } } if (dev->driver->dev_config_set(dev->driver_index, SR_HWCAP_PROBECONFIG, (char *)dev->probes) != SR_OK) { g_critical("Failed to configure probes."); sr_session_destroy(); return; } if (sr_session_start() != SR_OK) { g_critical("Failed to start session."); sr_session_destroy(); return; } if (opt_continuous) add_anykey(); sr_session_run(); if (opt_continuous) clear_anykey(); if (opt_output_file && default_output_format) { if (sr_session_save(opt_output_file) != SR_OK) g_critical("Failed to save session."); } sr_session_destroy(); }