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.c75
1 files changed, 69 insertions, 6 deletions
diff --git a/utils/nwztools/scsitools/scsitool.c b/utils/nwztools/scsitools/scsitool.c
index 6c3527713e..a90729a3d5 100644
--- a/utils/nwztools/scsitools/scsitool.c
+++ b/utils/nwztools/scsitools/scsitool.c
@@ -512,17 +512,48 @@ int get_dnk_nvp(int argc, char **argv)
512 return 0; 512 return 0;
513} 513}
514 514
515struct dpcc_devinfo_t
516{
517 uint8_t vendor_identification[8];
518 uint8_t product_identification[16];
519 uint8_t product_revision[4];
520 uint8_t product_sub_revision[4];
521 uint8_t storage_size[4];
522 uint8_t serial_number[16];
523 uint8_t vendor_specific[32];
524} __attribute__((packed));
525
526void dpcc_print_devinfo(void *buffer, int buf_size)
527{
528 if(buf_size < sizeof(struct dpcc_devinfo_t))
529 {
530 cprintf(GREY, "Cannot parse DEVINFO: buffer too small\n");
531 return;
532 }
533 struct dpcc_devinfo_t *devinfo = buffer;
534 cprintf_field("Vendor identification: ", "%.8s\n", devinfo->vendor_identification);
535 cprintf_field("Product identification: ", "%.16s\n", devinfo->product_identification);
536 cprintf_field("Product revision: ", "%.4s\n", devinfo->product_revision);
537 cprintf_field("Product sub revision: ", "%.4s\n", devinfo->product_sub_revision);
538 cprintf_field("Storage size: ", "%.4s\n", devinfo->storage_size);
539 cprintf_field("Serial number: ", "%.32s\n", devinfo->serial_number);
540 cprintf_field("Vendor specific: ", "%.32s\n", devinfo->vendor_specific);
541}
542
543typedef void (*dpcc_print_func_t)(void *buffer, int buf_size);
544
515struct dpcc_prop_t 545struct dpcc_prop_t
516{ 546{
517 char *user_name; 547 char *user_name;
518 char name[7]; 548 char name[7];
519 uint8_t cdb1; 549 uint8_t cdb1; // flags: bit 0 means size flag (means size in paragraph)
520 int size; 550 int size;
551 dpcc_print_func_t print_func;
521}; 552};
522 553
523struct dpcc_prop_t dpcc_prop_list[] = 554struct dpcc_prop_t dpcc_prop_list[] =
524{ 555{
525 { "dev_info", "DEVINFO", 0, 0x80 }, 556 { "dev_info", "DEVINFO", 0, 0x80, dpcc_print_devinfo },
526 /* there are more but they are very obscure */ 557 /* there are more but they are very obscure */
527}; 558};
528 559
@@ -534,7 +565,7 @@ int do_dpcc_cmd(uint32_t cmd, struct dpcc_prop_t *prop, void *buffer, int *buffe
534 cdb[2] = cmd; 565 cdb[2] = cmd;
535 if(cmd == 0) 566 if(cmd == 0)
536 { 567 {
537 strncpy((char *)(cdb + 3), prop->name, 7); // warning: erase cdb[10] ! 568 memcpy((char *)(cdb + 3), prop->name, 7);
538 cdb[1] = prop->cdb1; 569 cdb[1] = prop->cdb1;
539 if(prop->cdb1 & 1) 570 if(prop->cdb1 & 1)
540 cdb[10] = (*buffer_size + 15) / 16; 571 cdb[10] = (*buffer_size + 15) / 16;
@@ -575,7 +606,7 @@ int get_dpcc_prop(int argc, char **argv)
575 for(unsigned i = 0; i < NR_DPCC_PROPS; i++) 606 for(unsigned i = 0; i < NR_DPCC_PROPS; i++)
576 if(strcmp(dpcc_prop_list[i].user_name, argv[0]) == 0) 607 if(strcmp(dpcc_prop_list[i].user_name, argv[0]) == 0)
577 prop = dpcc_prop_list[i]; 608 prop = dpcc_prop_list[i];
578 if(prop.user_name[0] == 0) 609 if(prop.user_name == 0)
579 { 610 {
580 cprintf(GREY, "Unknown property '%s'\n", argv[0]); 611 cprintf(GREY, "Unknown property '%s'\n", argv[0]);
581 return 1; 612 return 1;
@@ -641,7 +672,35 @@ int get_dev_info(int argc, char **argv)
641 (void )argv; 672 (void )argv;
642 uint8_t cdb[12] = {0xfc, 0, 0x20, 'd', 'b', 'm', 'n', 0, 0x80, 0, 0, 0}; 673 uint8_t cdb[12] = {0xfc, 0, 0x20, 'd', 'b', 'm', 'n', 0, 0x80, 0, 0, 0};
643 674
644 char *buffer = malloc(0x81); 675 char *buffer = malloc(0x80);
676 int buffer_size = 0x80;
677 uint8_t sense[32];
678 int sense_size = 32;
679
680 int ret = do_scsi(cdb, 12, DO_READ, sense, &sense_size, buffer, &buffer_size);
681 if(ret < 0)
682 return ret;
683 ret = do_sense_analysis(ret, sense, sense_size);
684 if(ret)
685 {
686 cprintf(GREY, "An error occured during request\n");
687 return ret;
688 }
689 buffer[buffer_size] = 0;
690 cprintf_field("Raw device info:", "\n");
691 print_hex(buffer, buffer_size);
692 // the 16 first bytes are 'DEVINFO', 0x80, followed by zeroes
693 dpcc_print_devinfo(buffer + 16, buffer_size - 16);
694 return 0;
695}
696
697int get_dhp(int argc, char **argv)
698{
699 (void) argc;
700 (void )argv;
701 uint8_t cdb[12] = {0xfc, 0, 'D', 'd', 'h', 'p', 0, 0, 0, 0, 0, 0};
702
703 char *buffer = malloc(0x80);
645 int buffer_size = 0x80; 704 int buffer_size = 0x80;
646 uint8_t sense[32]; 705 uint8_t sense[32];
647 int sense_size = 32; 706 int sense_size = 32;
@@ -651,9 +710,12 @@ int get_dev_info(int argc, char **argv)
651 return ret; 710 return ret;
652 ret = do_sense_analysis(ret, sense, sense_size); 711 ret = do_sense_analysis(ret, sense, sense_size);
653 if(ret) 712 if(ret)
713 {
714 cprintf(GREY, "An error occured during request\n");
654 return ret; 715 return ret;
716 }
655 buffer[buffer_size] = 0; 717 buffer[buffer_size] = 0;
656 cprintf_field("Device Info:", "\n"); 718 cprintf_field("Destination/Headphones:", "\n");
657 print_hex(buffer, buffer_size); 719 print_hex(buffer, buffer_size);
658 return 0; 720 return 0;
659} 721}
@@ -839,6 +901,7 @@ struct cmd_t cmd_list[] =
839 { "get_dpcc_prop", "Get DPCC property", get_dpcc_prop }, 901 { "get_dpcc_prop", "Get DPCC property", get_dpcc_prop },
840 { "get_user_time", "Get user time", get_user_time }, 902 { "get_user_time", "Get user time", get_user_time },
841 { "get_dev_info", "Get device info", get_dev_info }, 903 { "get_dev_info", "Get device info", get_dev_info },
904 { "get_dhp", "Get destination headphones", get_dhp },
842 { "do_fw_upgrade", "Do a firmware upgrade", do_fw_upgrade }, 905 { "do_fw_upgrade", "Do a firmware upgrade", do_fw_upgrade },
843 { "dest_tool", "Get/Set destination and sound pressure regulation", do_dest }, 906 { "dest_tool", "Get/Set destination and sound pressure regulation", do_dest },
844}; 907};