summaryrefslogtreecommitdiff
path: root/utils/nwztools/scsitools/scsitool.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/nwztools/scsitools/scsitool.c')
-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 @@
39bool g_debug = false; 39bool g_debug = false;
40const char *g_force_series = NULL; 40const char *g_force_series = NULL;
41char *g_out_prefix = NULL; 41char *g_out_prefix = NULL;
42bool g_relaxed = false;
43rb_scsi_device_t g_dev; 42rb_scsi_device_t g_dev;
44 43
45static void print_hex(void *_buffer, int buffer_size) 44static 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
364int 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 */
364int 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 */
413int write_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, int size) 399int 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
447int get_dnk_nvp(int argc, char **argv) 425int 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 }