diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2017-01-08 16:07:18 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2017-01-08 16:07:18 +0100 |
commit | 1895af8e15474f87b6b34ca7a4e04425cf36c7ec (patch) | |
tree | 1f2744270117cc4c11d4ea9057a4bc163550dd45 /utils/nwztools/scsitools | |
parent | 26774ece35dd435345ca862a4d09ac94ed89e47b (diff) |
nwztools/scitool: rework node size, remove relaxed mode
The cool now takes the database as a hint and will not complain if the device
returns less data. The tool also supports user provided size and raw node numbers
that are not in the database (advanced usage).
Change-Id: I8cec536718d7eff01c7803bea648d6122b82377a
Diffstat (limited to 'utils/nwztools/scsitools')
-rw-r--r-- | utils/nwztools/scsitools/scsitool.c | 113 |
1 files changed, 69 insertions, 44 deletions
diff --git a/utils/nwztools/scsitools/scsitool.c b/utils/nwztools/scsitools/scsitool.c index ad7586a452..46951fdbbb 100644 --- a/utils/nwztools/scsitools/scsitool.c +++ b/utils/nwztools/scsitools/scsitool.c @@ -39,7 +39,6 @@ bool g_debug = false; const char *g_force_series = NULL; char *g_out_prefix = NULL; -bool g_relaxed = false; rb_scsi_device_t g_dev; static void print_hex(void *_buffer, int buffer_size) @@ -360,17 +359,10 @@ int get_model_and_series(int *model_index, int *series_index) return 0; } -/* read nvp node, retrun nonzero on error, update size to actual length */ -int read_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, size_t *size) +/* Read nvp node, retrun nonzero on error, update size to actual length. The + * index is the raw node number sent to the device */ +int read_nvp_node(int node_index, void *buffer, size_t *size) { - int node_index = NWZ_NVP_INVALID; - if(nwz_series[series_index].nvp_index) - node_index = (*nwz_series[series_index].nvp_index)[node]; - if(node_index == NWZ_NVP_INVALID) - { - printf("This device doesn't have node '%s'\n", nwz_nvp[node].name); - return 5; - } /* the returned data has a 4 byte header: * - byte 0/1 is the para_noise index, written as a 16bit big-endian number * - byte 2/3 is the node index, written as a 16-bit big-endian number @@ -394,12 +386,6 @@ int read_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, size cprintf(GREY, "Device responded with invalid data\n"); return 1; } - if(!g_relaxed && xfer_size - 4 != (int)*size) - { - free(xfer_buf); - cprintf(GREY, "Device didn't send the expected amount of data\n"); - return 7; - } *size = xfer_size - 4; /* unscramble and copy */ for(int i = 4, idx = get_big_endian16(xfer_buf); i < xfer_size; i++, idx++) @@ -410,16 +396,8 @@ int read_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, size } /* read nvp node, retrun nonzero on error */ -int write_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, int size) +int write_nvp_node(int node_index, void *buffer, int size) { - int node_index = NWZ_NVP_INVALID; - if(nwz_series[series_index].nvp_index) - node_index = (*nwz_series[series_index].nvp_index)[node]; - if(node_index == NWZ_NVP_INVALID) - { - printf("This device doesn't have node '%s'\n", nwz_nvp[node].name); - return 5; - } /* the data buffer is prepended with a 4 byte header: * - byte 0/1 is the para_noise index, written as a 16bit big-endian number * - byte 2/3 is the node index, written as a 16-bit big-endian number */ @@ -446,41 +424,84 @@ int write_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, int int get_dnk_nvp(int argc, char **argv) { - if(argc != 1) + if(argc != 1 && argc != 2) { printf("You must specify a known nvp node or a full node specification:\n"); printf("Node usage: <node>\n"); + printf("Node usage: <node> <size>\n"); printf("Nodes:\n"); for(unsigned i = 0; i < NWZ_NVP_COUNT; i++) printf(" %-6s%s\n", nwz_nvp[i].name, nwz_nvp[i].desc); + printf("You can also specify a decimal or hexadecimal value directly\n"); return 1; } int series_index, model_index; int ret = get_model_and_series(&model_index, &series_index); if(ret) return ret; + size_t size = 0; + /* maybe user specified an explicit size */ + if(argc == 2) + { + char *end; + size = strtoul(argv[1], &end, 0); + if(*end) + { + printf("Invalid user-specified size '%s'\n", argv[1]); + return 5; + } + } /* find entry in NVP */ - enum nwz_nvp_node_t node = NWZ_NVP_COUNT; + const char *node_name = argv[0]; + const char *node_desc = NULL; + int node_index = NWZ_NVP_INVALID; for(int i = 0; i < NWZ_NVP_COUNT; i++) - if(strcmp(nwz_nvp[i].name, argv[0]) == 0) - node = i; - if(node== NWZ_NVP_COUNT) + if(strcmp(nwz_nvp[i].name, node_name) == 0) + { + if(nwz_series[series_index].nvp_index) + node_index = (*nwz_series[series_index].nvp_index)[i]; + if(node_index == NWZ_NVP_INVALID) + { + printf("This device doesn't have node '%s'\n", node_name); + return 5; + } + node_desc = nwz_nvp[i].desc; + /* if not overriden, try to get size from database */ + if(size == 0) + size = nwz_nvp[i].size; + } + /* if we can't find it, maybe check if it's a number */ + if(node_index == NWZ_NVP_INVALID) { - printf("I don't know about node '%s'\n", argv[0]); + char *end; + node_index = strtol(node_name, &end, 0); + if(*end) + node_index = NWZ_NVP_INVALID; /* string is not a number */ + } + if(node_index == NWZ_NVP_INVALID) + { + printf("I don't know about node '%s'\n", node_name); return 4; } - size_t size = nwz_nvp[node].size; - /* in relaxed mode, always ask for a lot of data to make sure we get everything */ - if(g_relaxed) + /* if we don't have a size, take a big size to be sure */ + if(size == 0) + { size = 4096; + printf("Note: node size unknown, trying to read %u bytes\n", (unsigned)size); + } + if(g_debug) + printf("Asking device for %u bytes\n", (unsigned)size); + /* take the size in the database as a hint of the size, but the device could + * return less data */ uint8_t *buffer = malloc(size); - ret = read_nvp_node(series_index, node, buffer, &size); + ret = read_nvp_node(node_index, buffer, &size); if(ret != 0) { free(buffer); return ret; } - cprintf(GREEN, "%s:\n", nwz_nvp[node].name); + cprintf(GREEN, "%s (node %d%s%s):\n", node_name, node_index, + node_desc ? "," : "", node_desc ? node_desc : ""); print_hex(buffer, size); free(buffer); @@ -696,10 +717,18 @@ int do_dest(int argc, char **argv) /* get model/series */ int model_index, series_index; int ret = get_model_and_series(&model_index, &series_index); + int shp_index = NWZ_NVP_INVALID; + if(nwz_series[series_index].nvp_index) + shp_index = (*nwz_series[series_index].nvp_index)[NWZ_NVP_SHP]; + if(shp_index == NWZ_NVP_INVALID) + { + printf("This device doesn't have node 'shp'\n"); + return 5; + } /* in all cases, we need to read shp */ size_t size = nwz_nvp[NWZ_NVP_SHP].size; uint8_t *shp = malloc(size); - ret = read_nvp_node(series_index, NWZ_NVP_SHP, shp, &size); + ret = read_nvp_node(shp_index, shp, &size); if(ret != 0) { free(shp); @@ -770,7 +799,7 @@ int do_dest(int argc, char **argv) } set_little_endian32(shp, dst); set_little_endian32(shp + 4, sps); - int ret = write_nvp_node(series_index, NWZ_NVP_SHP, shp, size); + int ret = write_nvp_node(shp_index, shp, size); free(shp); return ret; } @@ -817,7 +846,6 @@ static void usage(void) printf(" -d/--debug Display debug messages\n"); printf(" -c/--no-color Disable color output\n"); printf(" -s/--series <name> Force series (disable auto-detection, use '?' for the list)\n"); - printf(" -r/--relaxed Relax length checks on nvp properties\n"); printf("Commands:\n"); for(unsigned i = 0; i < NR_CMDS; i++) printf(" %s\t%s\n", cmd_list[i].name, cmd_list[i].desc); @@ -837,7 +865,7 @@ int main(int argc, char **argv) {0, 0, 0, 0} }; - int c = getopt_long(argc, argv, "?dcfo:s:r", long_options, NULL); + int c = getopt_long(argc, argv, "?dcfo:s:", long_options, NULL); if(c == -1) break; switch(c) @@ -859,9 +887,6 @@ int main(int argc, char **argv) case 's': g_force_series = optarg; break; - case 'r': - g_relaxed = true; - break; default: abort(); } |