summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/nwztools/scsitools/scsitool.c113
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();
}