@@ -42,7 +42,7 @@ static void cli_classic_usage(const char *name)
#endif
"-p <programmername>[:<parameters>] [-c <chipname>]\n"
"[-E|(-r|-w|-v) <file>] [-l <layoutfile> [-i <imagename>]...] [-n] [-f]]\n"
- "[-V[V[V]]] [-o <logfile>]\n\n", name);
+ "[-V[V[V]]] [-o <logfile>] [-F]\n\n", name);
printf(" -h | --help print this help text\n"
" -R | --version print version (release)\n"
@@ -53,6 +53,7 @@ static void cli_classic_usage(const char *name)
" -V | --verbose more verbose output\n"
" -c | --chip <chipname> probe only for specified flash chip\n"
" -f | --force force specific operations (see man page)\n"
+ " -F | --enum choice chip automatically\n"
" -n | --noverify don't auto-verify\n"
" -l | --layout <layoutfile> read ROM layout from <layoutfile>\n"
" -i | --image <name> only flash image <name> from flash layout\n"
@@ -94,11 +95,14 @@ int main(int argc, char *argv[])
unsigned long size;
/* Probe for up to three flash chips. */
const struct flashchip *chip = NULL;
- struct flashctx flashes[3] = {{0}};
- struct flashctx *fill_flash;
+ struct flashctx flashes = {0};
+ struct flashctx *pflashes = NULL;
+ struct flashctx *psort = NULL;
+ struct flashctx *paddress = NULL;
const char *name;
int namelen, opt, i, j;
- int startchip = -1, chipcount = 0, option_index = 0, force = 0;
+ int startchip = -1, chipcount = 0, option_index = 0, force = 0,
+ chipenum = 0;
#if CONFIG_PRINT_WIKI == 1
int list_supported_wiki = 0;
#endif
@@ -106,8 +110,9 @@ int main(int argc, char *argv[])
int dont_verify_it = 0, list_supported = 0, operation_specified = 0;
enum programmer prog = PROGRAMMER_INVALID;
int ret = 0;
+ int ret_doit = 0;
- static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:Lzho:";
+ static const char optstring[] = "r:Rw:v:nVEfFc:l:i:p:Lzho:";
static const struct option long_options[] = {
{"read", 1, NULL, 'r'},
{"write", 1, NULL, 'w'},
@@ -117,6 +122,7 @@ int main(int argc, char *argv[])
{"chip", 1, NULL, 'c'},
{"verbose", 0, NULL, 'V'},
{"force", 0, NULL, 'f'},
+ {"enum", 0, NULL, 'F'},
{"layout", 1, NULL, 'l'},
{"image", 1, NULL, 'i'},
{"list-supported", 0, NULL, 'L'},
@@ -209,6 +215,9 @@ int main(int argc, char *argv[])
case 'f':
force = 1;
break;
+ case 'F':
+ chipenum = 1;
+ break;
case 'l':
if (layoutfile) {
fprintf(stderr, "Error: --layout specified "
@@ -425,22 +434,72 @@ int main(int argc, char *argv[])
for (j = 0; j < registered_programmer_count; j++) {
startchip = 0;
- while (chipcount < ARRAY_SIZE(flashes)) {
- startchip = probe_flash(®istered_programmers[j], startchip, &flashes[chipcount], 0);
+ while (1) {
+ paddress = pflashes;
+ if (chip_to_probe && chipcount)
+ break;
+ startchip = probe_flash(®istered_programmers[j], startchip, &flashes, 0);
if (startchip == -1)
break;
+ pflashes = calloc(1, sizeof(struct flashctx));
+ if (!pflashes) {
+ msg_gerr("Out of memory!\n");
+ exit(1);
+ }
+ memcpy(pflashes, &flashes, sizeof(struct flashctx));
+ /*
+ * add item and sort by voltage
+ */
+ if (paddress != NULL) {
+ for (psort = paddress; ; psort = psort->last) {
+ if (psort->chip->voltage.min >= pflashes->chip->voltage.min) {
+ pflashes->next = psort->next;
+ pflashes->last = psort;
+ psort->next = pflashes;
+ pflashes->head = &paddress;
+ if (psort == paddress)
+ paddress = pflashes;
+ else {
+ psort = pflashes->next;
+ psort->last = pflashes;
+ }
+ pflashes = paddress;
+ break;
+ }
+ if (psort->last == NULL) {
+ pflashes->next = psort;
+ pflashes->last = NULL;
+ psort->last = pflashes;
+ pflashes->head = &paddress;
+ pflashes = *(psort->head);
+ break;
+ }
+ }
+ } else {
+ pflashes->head = &paddress;
+ pflashes->last = paddress;
+ pflashes->next = NULL;
+ }
chipcount++;
startchip++;
}
}
-
if (chipcount > 1) {
- msg_cinfo("Multiple flash chips were detected: \"%s\"", flashes[0].chip->name);
- for (i = 1; i < chipcount; i++)
- msg_cinfo(", \"%s\"", flashes[i].chip->name);
- msg_cinfo("\nPlease specify which chip to use with the -c <chipname> option.\n");
- ret = 1;
- goto out_shutdown;
+ msg_cinfo("\nMultiple flash chips were detected:\n");
+ for (pflashes = *(pflashes->head); ; pflashes = pflashes->last) {
+ msg_cinfo("\"%s\" with minimal single supply voltage %dmV\n",
+ pflashes->chip->name, pflashes->chip->voltage.min);
+ if (pflashes->last == NULL) {
+ pflashes = *(pflashes->head);
+ break;
+ }
+ }
+ msg_cinfo("\nPlease specify which chip to use with the -c <chipname> option\n");
+ msg_cinfo("or use the -F enumeration option for trying choice chip automatically\n");
+ if (!chipenum) {
+ ret = 1;
+ goto out_shutdown;
+ }
} else if (!chipcount) {
msg_cinfo("No EEPROM/flash device found.\n");
if (!force || !chip_to_probe) {
@@ -468,7 +527,7 @@ int main(int argc, char *argv[])
"chip, using the first one.\n");
for (j = 0; j < registered_programmer_count; j++) {
pgm = ®istered_programmers[j];
- startchip = probe_flash(pgm, 0, &flashes[0], 1);
+ startchip = probe_flash(pgm, 0, pflashes, 1);
if (startchip != -1)
break;
}
@@ -479,26 +538,25 @@ int main(int argc, char *argv[])
goto out_shutdown;
}
msg_cinfo("Please note that forced reads most likely contain garbage.\n");
- ret = read_flash_to_file(&flashes[0], filename);
- free(flashes[0].chip);
+ ret = read_flash_to_file(pflashes, filename);
+ free(pflashes->chip);
goto out_shutdown;
}
ret = 1;
goto out_shutdown;
} else if (!chip_to_probe) {
/* repeat for convenience when looking at foreign logs */
- tempstr = flashbuses_to_text(flashes[0].chip->bustype);
+ tempstr = flashbuses_to_text(pflashes->chip->bustype);
msg_gdbg("Found %s flash chip \"%s\" (%d kB, %s).\n",
- flashes[0].chip->vendor, flashes[0].chip->name, flashes[0].chip->total_size, tempstr);
+ pflashes->chip->vendor, pflashes->chip->name, pflashes->chip->total_size, tempstr);
free(tempstr);
}
- fill_flash = &flashes[0];
-
- check_chip_supported(fill_flash->chip);
+for (pflashes = *(pflashes->head); ; pflashes = pflashes->last) {
+ check_chip_supported(pflashes->chip);
- size = fill_flash->chip->total_size * 1024;
- if (check_max_decode(fill_flash->pgm->buses_supported & fill_flash->chip->bustype, size) && (!force)) {
+ size = pflashes->chip->total_size * 1024;
+ if (check_max_decode(pflashes->pgm->buses_supported & pflashes->chip->bustype, size) && (!force)) {
msg_cerr("Chip is too big for this programmer (-V gives details). Use --force to override.\n");
ret = 1;
goto out_shutdown;
@@ -518,19 +576,28 @@ int main(int argc, char *argv[])
* Give the chip time to settle.
*/
programmer_delay(100000);
- ret |= doit(fill_flash, force, filename, read_it, write_it, erase_it, verify_it);
+ ret_doit = doit(pflashes, force, filename, read_it, write_it, erase_it, verify_it);
+ if (!ret_doit) {
+ ret |= ret_doit;
+ break;
+ }
+ if (pflashes->last == NULL) {
+ pflashes = *(pflashes->head);
+ ret |= ret_doit;
+ break;
+ }
+}
/* Note: doit() already calls programmer_shutdown(). */
goto out;
out_shutdown:
programmer_shutdown();
out:
- for (i = 0; i < chipcount; i++)
- free(flashes[i].chip);
-
+ free(flashes.chip);
free(filename);
free(layoutfile);
free(pparam);
+ free(pflashes);
/* clean up global variables */
free((char *)chip_to_probe); /* Silence! Freeing is not modifying contents. */
chip_to_probe = NULL;
@@ -172,6 +172,10 @@ struct flashctx {
/* Some flash devices have an additional register space. */
chipaddr virtual_registers;
struct registered_programmer *pgm;
+ /*pointer dynamic list*/
+ struct flashctx *last;
+ struct flashctx *next;
+ struct flashctx **head;
};
#define TEST_UNTESTED 0
@@ -1170,7 +1170,8 @@ int read_flash_to_file(struct flashctx *flash, const char *filename)
unsigned char *buf = calloc(size, sizeof(char));
int ret = 0;
- msg_cinfo("Reading flash... ");
+ msg_cinfo("Reading flash \"%s\" with minimal single supply voltage %dmV... ",
+ flash->chip->name, flash->chip->voltage.min);
if (!buf) {
msg_gerr("Memory allocation failed!\n");
msg_cinfo("FAILED.\n");