diff options
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 @@ | |||
39 | bool g_debug = false; | 39 | bool g_debug = false; |
40 | const char *g_force_series = NULL; | 40 | const char *g_force_series = NULL; |
41 | char *g_out_prefix = NULL; | 41 | char *g_out_prefix = NULL; |
42 | bool g_relaxed = false; | ||
43 | rb_scsi_device_t g_dev; | 42 | rb_scsi_device_t g_dev; |
44 | 43 | ||
45 | static void print_hex(void *_buffer, int buffer_size) | 44 | static void print_hex(void *_buffer, int buffer_size) |
@@ -360,17 +359,10 @@ int get_model_and_series(int *model_index, int *series_index) | |||
360 | return 0; | 359 | return 0; |
361 | } | 360 | } |
362 | 361 | ||
363 | /* read nvp node, retrun nonzero on error, update size to actual length */ | 362 | /* Read nvp node, retrun nonzero on error, update size to actual length. The |
364 | int read_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, size_t *size) | 363 | * index is the raw node number sent to the device */ |
364 | int read_nvp_node(int node_index, void *buffer, size_t *size) | ||
365 | { | 365 | { |
366 | int node_index = NWZ_NVP_INVALID; | ||
367 | if(nwz_series[series_index].nvp_index) | ||
368 | node_index = (*nwz_series[series_index].nvp_index)[node]; | ||
369 | if(node_index == NWZ_NVP_INVALID) | ||
370 | { | ||
371 | printf("This device doesn't have node '%s'\n", nwz_nvp[node].name); | ||
372 | return 5; | ||
373 | } | ||
374 | /* the returned data has a 4 byte header: | 366 | /* the returned data has a 4 byte header: |
375 | * - byte 0/1 is the para_noise index, written as a 16bit big-endian number | 367 | * - byte 0/1 is the para_noise index, written as a 16bit big-endian number |
376 | * - byte 2/3 is the node index, written as a 16-bit big-endian number | 368 | * - 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 | |||
394 | cprintf(GREY, "Device responded with invalid data\n"); | 386 | cprintf(GREY, "Device responded with invalid data\n"); |
395 | return 1; | 387 | return 1; |
396 | } | 388 | } |
397 | if(!g_relaxed && xfer_size - 4 != (int)*size) | ||
398 | { | ||
399 | free(xfer_buf); | ||
400 | cprintf(GREY, "Device didn't send the expected amount of data\n"); | ||
401 | return 7; | ||
402 | } | ||
403 | *size = xfer_size - 4; | 389 | *size = xfer_size - 4; |
404 | /* unscramble and copy */ | 390 | /* unscramble and copy */ |
405 | for(int i = 4, idx = get_big_endian16(xfer_buf); i < xfer_size; i++, idx++) | 391 | 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 | |||
410 | } | 396 | } |
411 | 397 | ||
412 | /* read nvp node, retrun nonzero on error */ | 398 | /* read nvp node, retrun nonzero on error */ |
413 | int write_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, int size) | 399 | int write_nvp_node(int node_index, void *buffer, int size) |
414 | { | 400 | { |
415 | int node_index = NWZ_NVP_INVALID; | ||
416 | if(nwz_series[series_index].nvp_index) | ||
417 | node_index = (*nwz_series[series_index].nvp_index)[node]; | ||
418 | if(node_index == NWZ_NVP_INVALID) | ||
419 | { | ||
420 | printf("This device doesn't have node '%s'\n", nwz_nvp[node].name); | ||
421 | return 5; | ||
422 | } | ||
423 | /* the data buffer is prepended with a 4 byte header: | 401 | /* the data buffer is prepended with a 4 byte header: |
424 | * - byte 0/1 is the para_noise index, written as a 16bit big-endian number | 402 | * - byte 0/1 is the para_noise index, written as a 16bit big-endian number |
425 | * - byte 2/3 is the node index, written as a 16-bit big-endian number */ | 403 | * - 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 | |||
446 | 424 | ||
447 | int get_dnk_nvp(int argc, char **argv) | 425 | int get_dnk_nvp(int argc, char **argv) |
448 | { | 426 | { |
449 | if(argc != 1) | 427 | if(argc != 1 && argc != 2) |
450 | { | 428 | { |
451 | printf("You must specify a known nvp node or a full node specification:\n"); | 429 | printf("You must specify a known nvp node or a full node specification:\n"); |
452 | printf("Node usage: <node>\n"); | 430 | printf("Node usage: <node>\n"); |
431 | printf("Node usage: <node> <size>\n"); | ||
453 | printf("Nodes:\n"); | 432 | printf("Nodes:\n"); |
454 | for(unsigned i = 0; i < NWZ_NVP_COUNT; i++) | 433 | for(unsigned i = 0; i < NWZ_NVP_COUNT; i++) |
455 | printf(" %-6s%s\n", nwz_nvp[i].name, nwz_nvp[i].desc); | 434 | printf(" %-6s%s\n", nwz_nvp[i].name, nwz_nvp[i].desc); |
435 | printf("You can also specify a decimal or hexadecimal value directly\n"); | ||
456 | return 1; | 436 | return 1; |
457 | } | 437 | } |
458 | int series_index, model_index; | 438 | int series_index, model_index; |
459 | int ret = get_model_and_series(&model_index, &series_index); | 439 | int ret = get_model_and_series(&model_index, &series_index); |
460 | if(ret) | 440 | if(ret) |
461 | return ret; | 441 | return ret; |
442 | size_t size = 0; | ||
443 | /* maybe user specified an explicit size */ | ||
444 | if(argc == 2) | ||
445 | { | ||
446 | char *end; | ||
447 | size = strtoul(argv[1], &end, 0); | ||
448 | if(*end) | ||
449 | { | ||
450 | printf("Invalid user-specified size '%s'\n", argv[1]); | ||
451 | return 5; | ||
452 | } | ||
453 | } | ||
462 | /* find entry in NVP */ | 454 | /* find entry in NVP */ |
463 | enum nwz_nvp_node_t node = NWZ_NVP_COUNT; | 455 | const char *node_name = argv[0]; |
456 | const char *node_desc = NULL; | ||
457 | int node_index = NWZ_NVP_INVALID; | ||
464 | for(int i = 0; i < NWZ_NVP_COUNT; i++) | 458 | for(int i = 0; i < NWZ_NVP_COUNT; i++) |
465 | if(strcmp(nwz_nvp[i].name, argv[0]) == 0) | 459 | if(strcmp(nwz_nvp[i].name, node_name) == 0) |
466 | node = i; | 460 | { |
467 | if(node== NWZ_NVP_COUNT) | 461 | if(nwz_series[series_index].nvp_index) |
462 | node_index = (*nwz_series[series_index].nvp_index)[i]; | ||
463 | if(node_index == NWZ_NVP_INVALID) | ||
464 | { | ||
465 | printf("This device doesn't have node '%s'\n", node_name); | ||
466 | return 5; | ||
467 | } | ||
468 | node_desc = nwz_nvp[i].desc; | ||
469 | /* if not overriden, try to get size from database */ | ||
470 | if(size == 0) | ||
471 | size = nwz_nvp[i].size; | ||
472 | } | ||
473 | /* if we can't find it, maybe check if it's a number */ | ||
474 | if(node_index == NWZ_NVP_INVALID) | ||
468 | { | 475 | { |
469 | printf("I don't know about node '%s'\n", argv[0]); | 476 | char *end; |
477 | node_index = strtol(node_name, &end, 0); | ||
478 | if(*end) | ||
479 | node_index = NWZ_NVP_INVALID; /* string is not a number */ | ||
480 | } | ||
481 | if(node_index == NWZ_NVP_INVALID) | ||
482 | { | ||
483 | printf("I don't know about node '%s'\n", node_name); | ||
470 | return 4; | 484 | return 4; |
471 | } | 485 | } |
472 | size_t size = nwz_nvp[node].size; | 486 | /* if we don't have a size, take a big size to be sure */ |
473 | /* in relaxed mode, always ask for a lot of data to make sure we get everything */ | 487 | if(size == 0) |
474 | if(g_relaxed) | 488 | { |
475 | size = 4096; | 489 | size = 4096; |
490 | printf("Note: node size unknown, trying to read %u bytes\n", (unsigned)size); | ||
491 | } | ||
492 | if(g_debug) | ||
493 | printf("Asking device for %u bytes\n", (unsigned)size); | ||
494 | /* take the size in the database as a hint of the size, but the device could | ||
495 | * return less data */ | ||
476 | uint8_t *buffer = malloc(size); | 496 | uint8_t *buffer = malloc(size); |
477 | ret = read_nvp_node(series_index, node, buffer, &size); | 497 | ret = read_nvp_node(node_index, buffer, &size); |
478 | if(ret != 0) | 498 | if(ret != 0) |
479 | { | 499 | { |
480 | free(buffer); | 500 | free(buffer); |
481 | return ret; | 501 | return ret; |
482 | } | 502 | } |
483 | cprintf(GREEN, "%s:\n", nwz_nvp[node].name); | 503 | cprintf(GREEN, "%s (node %d%s%s):\n", node_name, node_index, |
504 | node_desc ? "," : "", node_desc ? node_desc : ""); | ||
484 | print_hex(buffer, size); | 505 | print_hex(buffer, size); |
485 | 506 | ||
486 | free(buffer); | 507 | free(buffer); |
@@ -696,10 +717,18 @@ int do_dest(int argc, char **argv) | |||
696 | /* get model/series */ | 717 | /* get model/series */ |
697 | int model_index, series_index; | 718 | int model_index, series_index; |
698 | int ret = get_model_and_series(&model_index, &series_index); | 719 | int ret = get_model_and_series(&model_index, &series_index); |
720 | int shp_index = NWZ_NVP_INVALID; | ||
721 | if(nwz_series[series_index].nvp_index) | ||
722 | shp_index = (*nwz_series[series_index].nvp_index)[NWZ_NVP_SHP]; | ||
723 | if(shp_index == NWZ_NVP_INVALID) | ||
724 | { | ||
725 | printf("This device doesn't have node 'shp'\n"); | ||
726 | return 5; | ||
727 | } | ||
699 | /* in all cases, we need to read shp */ | 728 | /* in all cases, we need to read shp */ |
700 | size_t size = nwz_nvp[NWZ_NVP_SHP].size; | 729 | size_t size = nwz_nvp[NWZ_NVP_SHP].size; |
701 | uint8_t *shp = malloc(size); | 730 | uint8_t *shp = malloc(size); |
702 | ret = read_nvp_node(series_index, NWZ_NVP_SHP, shp, &size); | 731 | ret = read_nvp_node(shp_index, shp, &size); |
703 | if(ret != 0) | 732 | if(ret != 0) |
704 | { | 733 | { |
705 | free(shp); | 734 | free(shp); |
@@ -770,7 +799,7 @@ int do_dest(int argc, char **argv) | |||
770 | } | 799 | } |
771 | set_little_endian32(shp, dst); | 800 | set_little_endian32(shp, dst); |
772 | set_little_endian32(shp + 4, sps); | 801 | set_little_endian32(shp + 4, sps); |
773 | int ret = write_nvp_node(series_index, NWZ_NVP_SHP, shp, size); | 802 | int ret = write_nvp_node(shp_index, shp, size); |
774 | free(shp); | 803 | free(shp); |
775 | return ret; | 804 | return ret; |
776 | } | 805 | } |
@@ -817,7 +846,6 @@ static void usage(void) | |||
817 | printf(" -d/--debug Display debug messages\n"); | 846 | printf(" -d/--debug Display debug messages\n"); |
818 | printf(" -c/--no-color Disable color output\n"); | 847 | printf(" -c/--no-color Disable color output\n"); |
819 | printf(" -s/--series <name> Force series (disable auto-detection, use '?' for the list)\n"); | 848 | printf(" -s/--series <name> Force series (disable auto-detection, use '?' for the list)\n"); |
820 | printf(" -r/--relaxed Relax length checks on nvp properties\n"); | ||
821 | printf("Commands:\n"); | 849 | printf("Commands:\n"); |
822 | for(unsigned i = 0; i < NR_CMDS; i++) | 850 | for(unsigned i = 0; i < NR_CMDS; i++) |
823 | printf(" %s\t%s\n", cmd_list[i].name, cmd_list[i].desc); | 851 | printf(" %s\t%s\n", cmd_list[i].name, cmd_list[i].desc); |
@@ -837,7 +865,7 @@ int main(int argc, char **argv) | |||
837 | {0, 0, 0, 0} | 865 | {0, 0, 0, 0} |
838 | }; | 866 | }; |
839 | 867 | ||
840 | int c = getopt_long(argc, argv, "?dcfo:s:r", long_options, NULL); | 868 | int c = getopt_long(argc, argv, "?dcfo:s:", long_options, NULL); |
841 | if(c == -1) | 869 | if(c == -1) |
842 | break; | 870 | break; |
843 | switch(c) | 871 | switch(c) |
@@ -859,9 +887,6 @@ int main(int argc, char **argv) | |||
859 | case 's': | 887 | case 's': |
860 | g_force_series = optarg; | 888 | g_force_series = optarg; |
861 | break; | 889 | break; |
862 | case 'r': | ||
863 | g_relaxed = true; | ||
864 | break; | ||
865 | default: | 890 | default: |
866 | abort(); | 891 | abort(); |
867 | } | 892 | } |