452
/* Print descriptor format sense descriptors (assumes sense buffer is
498
/* Decode descriptor format sense descriptors (assumes sense buffer is
453
499
in descriptor format) */
455
501
sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
456
int buff_len, char * buff)
458
int add_sen_len, add_len, desc_len, k, j, sense_key, processed;
504
int add_sb_len, add_d_len, desc_len, k, j, sense_key, processed;
459
505
int n, progress, pr, rem;
460
506
const unsigned char * descp;
461
507
const char * dtsp = " >> descriptor too short";
464
if ((NULL == buff) || (buff_len <= 0))
467
if ((sb_len < 8) || (0 == (add_sen_len = sense_buffer[7])))
469
add_sen_len = (add_sen_len < (sb_len - 8)) ? add_sen_len : (sb_len - 8);
470
descp = &sense_buffer[8];
509
if ((NULL == b) || (blen <= 0))
512
if ((sb_len < 8) || (0 == (add_sb_len = sense_buffer[7])))
514
add_sb_len = (add_sb_len < (sb_len - 8)) ? add_sb_len : (sb_len - 8);
471
515
sense_key = (sense_buffer[1] & 0xf);
472
for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) {
474
add_len = (k < (add_sen_len - 1)) ? descp[1] : -1;
475
if ((k + add_len + 2) > add_sen_len)
476
add_len = add_sen_len - k - 2;
477
desc_len = add_len + 2;
479
n += sprintf(b + n, " Descriptor type: ");
517
for (descp = (sense_buffer + 8), k = 0, n = 0;
518
(k < add_sb_len) && (n < blen);
519
k += desc_len, descp += desc_len) {
520
add_d_len = (k < (add_sb_len - 1)) ? descp[1] : -1;
521
if ((k + add_d_len + 2) > add_sb_len)
522
add_d_len = add_sb_len - k - 2;
523
desc_len = add_d_len + 2;
524
n += my_snprintf(b + n, blen - n, " Descriptor type: ");
481
526
switch (descp[0]) {
483
n += sprintf(b + n, "Information\n");
484
if ((add_len >= 10) && (0x80 & descp[2])) {
485
n += sprintf(b + n, " 0x");
528
n += my_snprintf(b + n, blen - n, "Information\n");
529
if ((add_d_len >= 10) && (0x80 & descp[2])) {
530
n += my_snprintf(b + n, blen - n, " 0x");
486
531
for (j = 0; j < 8; ++j)
487
n += sprintf(b + n, "%02x", descp[4 + j]);
488
n += sprintf(b + n, "\n");
532
n += my_snprintf(b + n, blen - n, "%02x", descp[4 + j]);
533
n += my_snprintf(b + n, blen - n, "\n");
490
n += sprintf(b + n, "%s\n", dtsp);
535
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
495
n += sprintf(b + n, "Command specific\n");
497
n += sprintf(b + n, " 0x");
540
n += my_snprintf(b + n, blen - n, "Command specific\n");
541
if (add_d_len >= 10) {
542
n += my_snprintf(b + n, blen - n, " 0x");
498
543
for (j = 0; j < 8; ++j)
499
n += sprintf(b + n, "%02x", descp[4 + j]);
500
n += sprintf(b + n, "\n");
544
n += my_snprintf(b + n, blen - n, "%02x", descp[4 + j]);
545
n += my_snprintf(b + n, blen - n, "\n");
502
n += sprintf(b + n, "%s\n", dtsp);
547
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
507
n += sprintf(b + n, "Sense key specific:");
552
n += my_snprintf(b + n, blen - n, "Sense key specific:");
508
553
switch (sense_key) {
509
554
case SPC_SK_ILLEGAL_REQUEST:
510
n += sprintf(b + n, " Field pointer\n");
512
n += sprintf(b + n, "%s\n", dtsp);
555
n += my_snprintf(b + n, blen - n, " Field pointer\n");
557
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
516
n += sprintf(b + n, " Error in %s byte %d",
517
(descp[4] & 0x40) ? "Command" : "Data",
518
(descp[5] << 8) | descp[6]);
561
n += my_snprintf(b + n, blen - n, " Error in %s byte %d",
562
(descp[4] & 0x40) ? "Command" : "Data",
563
(descp[5] << 8) | descp[6]);
519
564
if (descp[4] & 0x08) {
520
n += sprintf(b + n, " bit %d\n", descp[4] & 0x07);
565
n += my_snprintf(b + n, blen - n, " bit %d\n",
522
n += sprintf(b + n, "\n");
568
n += my_snprintf(b + n, blen - n, "\n");
524
570
case SPC_SK_HARDWARE_ERROR:
525
571
case SPC_SK_MEDIUM_ERROR:
526
572
case SPC_SK_RECOVERED_ERROR:
527
n += sprintf(b + n, " Actual retry count\n");
529
n += sprintf(b + n, "%s\n", dtsp);
573
n += my_snprintf(b + n, blen - n, " Actual retry count\n");
575
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
533
n += sprintf(b + n, " 0x%02x%02x\n", descp[5],
579
n += my_snprintf(b + n, blen - n," 0x%02x%02x\n", descp[5],
536
582
case SPC_SK_NO_SENSE:
537
583
case SPC_SK_NOT_READY:
538
n += sprintf(b + n, " Progress indication: ");
540
n += sprintf(b + n, "%s\n", dtsp);
584
n += my_snprintf(b + n, blen - n, " Progress indication: ");
586
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
544
590
progress = (descp[5] << 8) + descp[6];
545
591
pr = (progress * 100) / 65536;
546
rem = ((progress * 100) % 65536) / 655;
547
n += sprintf(b + n, "%d.%02d%%\n", pr, rem);
592
rem = ((progress * 100) % 65536) / 656;
593
n += my_snprintf(b + n, blen - n, "%d.%02d%%\n", pr, rem);
549
595
case SPC_SK_COPY_ABORTED:
550
n += sprintf(b + n, " Segment pointer\n");
552
n += sprintf(b + n, "%s\n", dtsp);
596
n += my_snprintf(b + n, blen - n, " Segment pointer\n");
598
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
556
n += sprintf(b + n, " Relative to start of %s, byte %d",
557
(descp[4] & 0x20) ? "segment descriptor" :
559
(descp[5] << 8) | descp[6]);
602
n += my_snprintf(b + n, blen - n, " Relative to start of %s, "
604
(descp[4] & 0x20) ? "segment descriptor" :
606
(descp[5] << 8) | descp[6]);
560
607
if (descp[4] & 0x08)
561
n += sprintf(b + n, " bit %d\n", descp[4] & 0x07);
608
n += my_snprintf(b + n, blen - n, " bit %d\n",
563
n += sprintf(b + n, "\n");
611
n += my_snprintf(b + n, blen - n, "\n");
565
613
case SPC_SK_UNIT_ATTENTION:
566
n += sprintf(b + n, " Unit attention condition queue: ");
567
n += sprintf(b + n, "overflow flag is %d\n",
614
n += my_snprintf(b + n, blen - n, " Unit attention condition "
616
n += my_snprintf(b + n, blen - n, "overflow flag is %d\n",
568
617
!!(descp[4] & 0x1));
571
n += sprintf(b + n, " Sense_key: 0x%x unexpected\n",
620
n += my_snprintf(b + n, blen - n, " Sense_key: 0x%x "
621
"unexpected\n", sense_key);
578
n += sprintf(b + n, "Field replaceable unit\n");
580
n += sprintf(b + n, " code=0x%x\n", descp[3]);
627
n += my_snprintf(b + n, blen - n, "Field replaceable unit\n");
629
n += my_snprintf(b + n, blen - n, " code=0x%x\n",
582
n += sprintf(b + n, "%s\n", dtsp);
632
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
587
n += sprintf(b + n, "Stream commands\n");
637
n += my_snprintf(b + n, blen - n, "Stream commands\n");
638
if (add_d_len >= 2) {
589
639
if (descp[3] & 0x80)
590
n += sprintf(b + n, " FILEMARK");
640
n += my_snprintf(b + n, blen - n, " FILEMARK");
591
641
if (descp[3] & 0x40)
592
n += sprintf(b + n, " End Of Medium (EOM)");
642
n += my_snprintf(b + n, blen - n, " End Of Medium "
593
644
if (descp[3] & 0x20)
594
n += sprintf(b + n, " Incorrect Length Indicator "
596
n += sprintf(b + n, "\n");
645
n += my_snprintf(b + n, blen - n, " Incorrect Length "
647
n += my_snprintf(b + n, blen - n, "\n");
598
n += sprintf(b + n, "%s\n", dtsp);
649
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
603
n += sprintf(b + n, "Block commands\n");
605
n += sprintf(b + n, " Incorrect Length Indicator "
606
"(ILI) %s\n", (descp[3] & 0x20) ? "set" : "clear");
654
n += my_snprintf(b + n, blen - n, "Block commands\n");
656
n += my_snprintf(b + n, blen - n, " Incorrect Length "
657
"Indicator (ILI) %s\n",
658
(descp[3] & 0x20) ? "set" : "clear");
608
n += sprintf(b + n, "%s\n", dtsp);
660
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
613
n += sprintf(b + n, "OSD object identification\n");
665
n += my_snprintf(b + n, blen - n, "OSD object identification\n");
617
n += sprintf(b + n, "OSD response integrity check value\n");
669
n += my_snprintf(b + n, blen - n, "OSD response integrity check "
621
n += sprintf(b + n, "OSD attribute identification\n");
674
n += my_snprintf(b + n, blen - n, "OSD attribute "
625
n += sprintf(b + n, "ATA Status Return\n");
678
case 9: /* this is defined in SAT (and SAT-2) */
679
n += my_snprintf(b + n, blen - n, "ATA Status Return\n");
680
if (add_d_len >= 12) {
627
681
int extend, sector_count;
629
683
extend = descp[2] & 1;
630
684
sector_count = descp[5] + (extend ? (descp[4] << 8) : 0);
631
n += sprintf(b + n, " extend=%d error=0x%x "
632
" sector_count=0x%x\n", extend, descp[3],
685
n += my_snprintf(b + n, blen - n, " extend=%d error=0x%x "
686
" sector_count=0x%x\n", extend, descp[3],
635
n += sprintf(b + n, " lba=0x%02x%02x%02x%02x%02x%02x\n",
636
descp[10], descp[8], descp[6],
637
descp[11], descp[9], descp[7]);
689
n += my_snprintf(b + n, blen - n, " "
690
"lba=0x%02x%02x%02x%02x%02x%02x\n",
691
descp[10], descp[8], descp[6],
692
descp[11], descp[9], descp[7]);
639
n += sprintf(b + n, " lba=0x%02x%02x%02x\n",
640
descp[11], descp[9], descp[7]);
641
n += sprintf(b + n, " device=0x%x status=0x%x\n",
642
descp[12], descp[13]);
694
n += my_snprintf(b + n, blen - n, " "
695
"lba=0x%02x%02x%02x\n",
696
descp[11], descp[9], descp[7]);
697
n += my_snprintf(b + n, blen - n, " device=0x%x "
698
"status=0x%x\n", descp[12], descp[13]);
644
n += sprintf(b + n, "%s\n", dtsp);
700
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
648
case 0xa: /* Added in SPC-4 rev 17 */
649
n += sprintf(b + n, "Progress indication\n");
651
n += sprintf(b + n, "%s\n", dtsp);
705
/* Added in SPC-4 rev 17, became 'Another ...' in rev 34 */
706
n += my_snprintf(b + n, blen - n, "Another progress "
709
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
655
713
progress = (descp[6] << 8) + descp[7];
656
714
pr = (progress * 100) / 65536;
657
rem = ((progress * 100) % 65536) / 655;
658
n += sprintf(b + n, " %d.02%d%%", pr, rem);
659
n += sprintf(b + n, " [sense_key=0x%x asc,ascq=0x%x,0x%x]\n",
660
descp[2], descp[3], descp[4]);
715
rem = ((progress * 100) % 65536) / 656;
716
n += my_snprintf(b + n, blen - n, " %d.02%d%%", pr, rem);
717
n += my_snprintf(b + n, blen - n, " [sense_key=0x%x "
718
"asc,ascq=0x%x,0x%x]\n",
719
descp[2], descp[3], descp[4]);
662
721
case 0xb: /* Added in SPC-4 rev 23, defined in SBC-3 rev 22 */
663
n += sprintf(b + n, "User data segment referral\n");
665
n += sprintf(b + n, "%s\n", dtsp);
722
n += my_snprintf(b + n, blen - n, "User data segment referral\n");
724
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
669
n += uds_referral_descriptor_str(b + n, descp, add_len);
728
n += uds_referral_descriptor_str(b + n, blen - n, descp,
671
731
case 0xc: /* Added in SPC-4 rev 28 */
672
n += sprintf(b + n, "Forwarded sense data\n");
674
n += sprintf(b + n, "%s\n", dtsp);
732
n += my_snprintf(b + n, blen - n, "Forwarded sense data\n");
734
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
678
n += sprintf(b + n, " FSDT: %s\n",
679
(descp[2] & 0x80) ? "set" : "clear");
738
n += my_snprintf(b + n, blen - n, " FSDT: %s\n",
739
(descp[2] & 0x80) ? "set" : "clear");
680
740
j = descp[2] & 0xf;
682
n += sprintf(b + n, " Sense data source: %s\n",
742
n += my_snprintf(b + n, blen - n, " Sense data source: "
743
"%s\n", sdata_src[j]);
685
n += sprintf(b + n, " Sense data source: reserved [%d]\n",
745
n += my_snprintf(b + n, blen - n, " Sense data source: "
746
"reserved [%d]\n", j);
690
750
sg_get_scsi_status_str(descp[3], sizeof(c) - 1, c);
691
751
c[sizeof(c) - 1] = '\0';
692
n += sprintf(b + n, " Forwarded status: %s\n", c);
752
n += my_snprintf(b + n, blen - n, " Forwarded status: "
694
755
/* recursing; hope not to get carried away */
695
n += sprintf(b + n, " vvvvvvvvvvvvvvvv\n");
696
sg_get_sense_str(NULL, descp + 4, add_len - 2, 0,
756
n += my_snprintf(b + n, blen - n, " vvvvvvvvvvvvvvvv\n");
757
sg_get_sense_str(NULL, descp + 4, add_d_len - 2, 0,
698
n += sprintf(b + n, "%s", c);
699
n += sprintf(b + n, " ^^^^^^^^^^^^^^^^\n");
759
n += my_snprintf(b + n, blen - n, "%s", c);
760
n += my_snprintf(b + n, blen - n, " ^^^^^^^^^^^^^^^^\n");
704
765
if (descp[0] >= 0x80)
705
n += sprintf(b + n, "Vendor specific [0x%x]\n", descp[0]);
766
n += my_snprintf(b + n, blen - n, "Vendor specific [0x%x]\n",
707
n += sprintf(b + n, "Unknown [0x%x]\n", descp[0]);
769
n += my_snprintf(b + n, blen - n, "Unknown [0x%x]\n",
711
774
if (! processed) {
713
n += sprintf(b + n, " ");
714
for (j = 0; j < add_len; ++j) {
776
n += my_snprintf(b + n, blen - n, " ");
777
for (j = 0; j < add_d_len; ++j) {
715
778
if ((j > 0) && (0 == (j % 24)))
716
n += sprintf(b + n, "\n ");
717
n += sprintf(b + n, "%02x ", descp[j + 2]);
779
n += my_snprintf(b + n, blen - n, "\n ");
780
n += my_snprintf(b + n, blen - n, "%02x ", descp[j + 2]);
719
n += sprintf(b + n, "\n");
782
n += my_snprintf(b + n, blen - n, "\n");
723
n += sprintf(b + n, " short descriptor\n");
725
if ((n + j) >= buff_len) {
726
strncpy(buff + j, b, buff_len - j);
727
buff[buff_len - 1] = '\0';
786
n += my_snprintf(b + n, blen - n, " short descriptor\n");
790
/* Decode SAT ATA PASS-THROUGH fixed format sense */
792
sg_get_sense_sat_pt_fixed_str(const unsigned char * sp, int slen, int blen,
797
slen = slen; /* suppress warning */
800
if (SPC_SK_RECOVERED_ERROR != (0xf & sp[2]))
801
n += my_snprintf(b + n, blen - n, " >> expected Sense key: "
802
"Recovered Error ??\n");
803
n += my_snprintf(b + n, blen - n, " error=0x%x, status=0x%x, "
804
"device=0x%x, sector_count(7:0)=0x%x%c\n", sp[3], sp[4],
805
sp[5], sp[6], ((0x40 & sp[8]) ? '+' : ' '));
806
n += my_snprintf(b + n, blen - n, " extend=%d, log_index=0x%x, "
807
"lba_high,mid,low(7:0)=0x%x,0x%x,0x%x%c\n",
808
(!!(0x80 & sp[8])), (0xf & sp[8]), sp[9], sp[10], sp[11],
809
((0x20 & sp[8]) ? '+' : ' '));
736
812
/* Fetch sense information */
738
814
sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
739
815
int sb_len, int raw_sinfo, int buff_len, char * buff)
741
int len, valid, progress, n, r, pr, rem;
817
int len, valid, progress, n, r, pr, rem, blen;
742
818
unsigned int info;
743
819
int descriptor_format = 0;
744
const char * error = NULL;
821
const char * ebp = NULL;
745
822
char error_buff[64];
747
824
struct sg_scsi_sense_hdr ssh;
749
826
if ((NULL == buff) || (buff_len <= 0))
751
buff[buff_len - 1] = '\0';
828
else if (1 == buff_len) {
754
834
if (sb_len < 1) {
755
snprintf(buff, buff_len, "sense buffer empty\n");
759
n += snprintf(buff + n, buff_len - n, "%s: ", leadin);
835
my_snprintf(buff, buff_len, "sense buffer empty\n");
839
n += my_snprintf(buff + n, buff_len - n, "%s: ", leadin);
764
841
if (sg_scsi_normalize_sense(sense_buffer, sb_len, &ssh)) {
765
842
switch (ssh.response_code) {
766
843
case 0x70: /* fixed, current */
767
error = "Fixed format, current";
844
ebp = "Fixed format, current";
768
845
len = (sb_len > 7) ? (sense_buffer[7] + 8) : sb_len;
769
846
len = (len > sb_len) ? sb_len : len;
847
sdat_ovfl = (len > 2) ? !!(sense_buffer[2] & 0x10) : 0;
771
849
case 0x71: /* fixed, deferred */
772
850
/* error related to a previous command */
773
error = "Fixed format, <<<deferred>>>";
851
ebp = "Fixed format, <<<deferred>>>";
774
852
len = (sb_len > 7) ? (sense_buffer[7] + 8) : sb_len;
775
853
len = (len > sb_len) ? sb_len : len;
854
sdat_ovfl = (len > 2) ? !!(sense_buffer[2] & 0x10) : 0;
777
856
case 0x72: /* descriptor, current */
778
857
descriptor_format = 1;
779
error = "Descriptor format, current";
858
ebp = "Descriptor format, current";
859
sdat_ovfl = (sb_len > 4) ? !!(sense_buffer[4] & 0x80) : 0;
781
861
case 0x73: /* descriptor, deferred */
782
862
descriptor_format = 1;
783
error = "Descriptor format, <<<deferred>>>";
863
ebp = "Descriptor format, <<<deferred>>>";
864
sdat_ovfl = (sb_len > 4) ? !!(sense_buffer[4] & 0x80) : 0;
786
error = "Response code: 0x0 (?)";
867
ebp = "Response code: 0x0 (?)";
789
snprintf(error_buff, sizeof(error_buff),
790
"Unknown response code: 0x%x", ssh.response_code);
870
my_snprintf(error_buff, sizeof(error_buff),
871
"Unknown response code: 0x%x", ssh.response_code);
794
n += snprintf(buff + n, buff_len - n, " %s; Sense key: %s\n ",
795
error, sg_lib_sense_key_desc[ssh.sense_key]);
875
n += my_snprintf(buff + n, buff_len - n, " %s; Sense key: %s\n ",
876
ebp, sg_lib_sense_key_desc[ssh.sense_key]);
878
n += my_snprintf(buff + n, buff_len - n, "<<<Sense data "
798
880
if (descriptor_format) {
799
n += snprintf(buff + n, buff_len - n, "%s\n",
800
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
881
n += my_snprintf(buff + n, buff_len - n, "%s\n",
882
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
804
884
sg_get_sense_descriptors_str(sense_buffer, len, buff_len - n,
806
886
n = strlen(buff);
887
} else if ((len > 12) && (0 == ssh.asc) &&
888
(ASCQ_ATA_PT_INFO_AVAILABLE == ssh.ascq)) {
889
/* SAT ATA PASS-THROUGH fixed format */
890
n += my_snprintf(buff + n, buff_len - n, "%s\n",
891
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
893
sg_get_sense_sat_pt_fixed_str(sense_buffer, len, buff_len - n,
809
896
} else if (len > 2) { /* fixed format */
811
n += snprintf(buff + n, buff_len - n, "%s\n",
812
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
898
n += my_snprintf(buff + n, buff_len - n, "%s\n",
899
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
818
902
valid = sense_buffer[0] & 0x80;
821
905
(sense_buffer[4] << 16) | (sense_buffer[5] << 8) |
822
906
sense_buffer[6]);
824
r += sprintf(b + r, " Info fld=0x%x [%u] ", info,
908
r += my_snprintf(b + r, blen - r, " Info fld=0x%x [%u] ",
826
910
else if (info > 0)
827
r += sprintf(b + r, " Valid=0, Info fld=0x%x [%u] ",
911
r += my_snprintf(b + r, blen - r, " Valid=0, Info "
912
"fld=0x%x [%u] ", info, info);
831
915
if (sense_buffer[2] & 0xe0) {
832
916
if (sense_buffer[2] & 0x80)
833
r += sprintf(b + r, " FMK");
917
r += my_snprintf(b + r, blen - r, " FMK");
834
918
/* current command has read a filemark */
835
919
if (sense_buffer[2] & 0x40)
836
r += sprintf(b + r, " EOM");
920
r += my_snprintf(b + r, blen - r, " EOM");
837
921
/* end-of-medium condition exists */
838
922
if (sense_buffer[2] & 0x20)
839
r += sprintf(b + r, " ILI");
923
r += my_snprintf(b + r, blen - r, " ILI");
840
924
/* incorrect block length requested */
841
r += sprintf(b + r, "\n");
925
r += my_snprintf(b + r, blen - r, "\n");
842
926
} else if (valid || (info > 0))
843
r += sprintf(b + r, "\n");
927
r += my_snprintf(b + r, blen - r, "\n");
844
928
if ((len >= 14) && sense_buffer[14])
845
r += sprintf(b + r, " Field replaceable unit code: "
846
"%d\n", sense_buffer[14]);
929
r += my_snprintf(b + r, blen - r, " Field replaceable unit "
930
"code: %d\n", sense_buffer[14]);
847
931
if ((len >= 18) && (sense_buffer[15] & 0x80)) {
848
932
/* sense key specific decoding */
849
933
switch (ssh.sense_key) {
850
934
case SPC_SK_ILLEGAL_REQUEST:
851
r += sprintf(b + r, " Sense Key Specific: Error in "
852
"%s byte %d", (sense_buffer[15] & 0x40) ?
854
(sense_buffer[16] << 8) | sense_buffer[17]);
935
r += my_snprintf(b + r, blen - r, " Sense Key Specific: "
936
"Error in %s byte %d",
937
((sense_buffer[15] & 0x40) ? "Command" : "Data"),
938
(sense_buffer[16] << 8) | sense_buffer[17]);
855
939
if (sense_buffer[15] & 0x08)
856
r += sprintf(b + r, " bit %d\n",
857
sense_buffer[15] & 0x07);
940
r += my_snprintf(b + r, blen - r, " bit %d\n",
941
sense_buffer[15] & 0x07);
859
r += sprintf(b + r, "\n");
943
r += my_snprintf(b + r, blen - r, "\n");
861
945
case SPC_SK_NO_SENSE:
862
946
case SPC_SK_NOT_READY:
863
947
progress = (sense_buffer[16] << 8) + sense_buffer[17];
864
948
pr = (progress * 100) / 65536;
865
rem = ((progress * 100) % 65536) / 655;
866
r += sprintf(b + r, " Progress indication: %d.%02d%%\n",
949
rem = ((progress * 100) % 65536) / 656;
950
r += my_snprintf(b + r, blen - r, " Progress "
951
"indication: %d.%02d%%\n", pr, rem);
869
953
case SPC_SK_HARDWARE_ERROR:
870
954
case SPC_SK_MEDIUM_ERROR:
871
955
case SPC_SK_RECOVERED_ERROR:
872
r += sprintf(b + r, " Actual retry count: "
873
"0x%02x%02x\n", sense_buffer[16],
956
r += my_snprintf(b + r, blen - r, " Actual retry count: "
957
"0x%02x%02x\n", sense_buffer[16],
876
960
case SPC_SK_COPY_ABORTED:
877
r += sprintf(b + r, " Segment pointer: ");
878
r += sprintf(b + r, "Relative to start of %s, byte %d",
879
(sense_buffer[15] & 0x20) ?
880
"segment descriptor" : "parameter list",
881
(sense_buffer[16] << 8) + sense_buffer[17]);
961
r += my_snprintf(b + r, blen - r, " Segment pointer: ");
962
r += my_snprintf(b + r, blen - r, "Relative to start of "
964
((sense_buffer[15] & 0x20) ?
965
"segment descriptor" : "parameter list"),
966
((sense_buffer[16] << 8) +
882
968
if (sense_buffer[15] & 0x08)
883
r += sprintf(b + r, " bit %d\n",
884
sense_buffer[15] & 0x07);
969
r += my_snprintf(b + r, blen - r, " bit %d\n",
970
sense_buffer[15] & 0x07);
886
r += sprintf(b + r, "\n");
972
r += my_snprintf(b + r, blen - r, "\n");
888
974
case SPC_SK_UNIT_ATTENTION:
889
r += sprintf(b + r, " Unit attention condition queue: ");
890
r += sprintf(b + r, "overflow flag is %d\n",
891
!!(sense_buffer[15] & 0x1));
975
r += my_snprintf(b + r, blen - r, " Unit attention "
976
"condition queue: ");
977
r += my_snprintf(b + r, blen - r, "overflow flag is %d\n",
978
!!(sense_buffer[15] & 0x1));
894
r += sprintf(b + r, " Sense_key: 0x%x unexpected\n",
981
r += my_snprintf(b + r, blen - r, " Sense_key: 0x%x "
982
"unexpected\n", ssh.sense_key);
900
n += snprintf(buff + n, buff_len - n, "%s", b);
905
n += snprintf(buff + n, buff_len - n, " fixed descriptor "
906
"length too short, len=%d\n", len);
987
n += my_snprintf(buff + n, buff_len - n, "%s", b);
989
n += my_snprintf(buff + n, buff_len - n, " fixed descriptor "
990
"length too short, len=%d\n", len);
910
991
} else { /* non-extended SCSI-1 sense data ?? */
911
992
if (sb_len < 4) {
912
n += snprintf(buff + n, buff_len - n, "sense buffer too short "
913
"(4 byte minimum)\n");
993
n += my_snprintf(buff + n, buff_len - n, "sense buffer too short "
994
"(4 byte minimum)\n");
917
r += sprintf(b + r, "Probably uninitialized data.\n Try to view "
918
"as SCSI-1 non-extended sense:\n");
919
r += sprintf(b + r, " AdValid=%d Error class=%d Error code=%d\n",
920
!!(sense_buffer[0] & 0x80),
921
((sense_buffer[0] >> 4) & 0x7),
922
(sense_buffer[0] & 0xf));
998
r += my_snprintf(b + r, blen - r, "Probably uninitialized data.\n "
999
"Try to view as SCSI-1 non-extended sense:\n");
1000
r += my_snprintf(b + r, blen - r, " AdValid=%d Error class=%d "
1001
"Error code=%d\n", !!(sense_buffer[0] & 0x80),
1002
((sense_buffer[0] >> 4) & 0x7),
1003
(sense_buffer[0] & 0xf));
923
1004
if (sense_buffer[0] & 0x80)
924
r += sprintf(b + r, " lba=0x%x\n",
925
((sense_buffer[1] & 0x1f) << 16) +
926
(sense_buffer[2] << 8) + sense_buffer[3]);
927
n += snprintf(buff + n, buff_len - n, "%s\n", b);
1005
r += my_snprintf(b + r, blen - r, " lba=0x%x\n",
1006
((sense_buffer[1] & 0x1f) << 16) +
1007
(sense_buffer[2] << 8) + sense_buffer[3]);
1008
n += my_snprintf(buff + n, buff_len - n, "%s\n", b);
932
1011
len = 32; /* trim in case there is a lot of rubbish */
934
1013
if (raw_sinfo) {
935
n += snprintf(buff + n, buff_len - n, " Raw sense data (in hex):\n");
1014
n += my_snprintf(buff + n, buff_len - n, " Raw sense data (in hex):"
1016
if (n >= (buff_len - 1))
938
1018
dStrHexErr((const char *)sense_buffer, len, buff_len - n, buff + n);
1071
1156
if ((NULL == buff) || (buff_len < 1))
1158
else if (1 == buff_len) {
1073
1162
switch ((int)cmd_byte0) {
1074
1163
case SG_VARIABLE_LENGTH_CMD:
1075
1164
vnp = get_value_name(sg_lib_variable_length_arr, service_action,
1078
strncpy(buff, vnp->name, buff_len);
1167
my_snprintf(buff, buff_len, "%s", vnp->name);
1080
snprintf(buff, buff_len, "Variable length service action=0x%x",
1169
my_snprintf(buff, buff_len, "Variable length service action=0x%x",
1083
1172
case SG_MAINTENANCE_IN:
1084
1173
vnp = get_value_name(sg_lib_maint_in_arr, service_action, peri_type);
1086
strncpy(buff, vnp->name, buff_len);
1175
my_snprintf(buff, buff_len, "%s", vnp->name);
1088
snprintf(buff, buff_len, "Maintenance in service action=0x%x",
1177
my_snprintf(buff, buff_len, "Maintenance in service action=0x%x",
1091
1180
case SG_MAINTENANCE_OUT:
1092
1181
vnp = get_value_name(sg_lib_maint_out_arr, service_action, peri_type);
1094
strncpy(buff, vnp->name, buff_len);
1183
my_snprintf(buff, buff_len, "%s", vnp->name);
1096
snprintf(buff, buff_len, "Maintenance out service action=0x%x",
1185
my_snprintf(buff, buff_len, "Maintenance out service action=0x%x",
1099
1188
case SG_SERVICE_ACTION_IN_12:
1100
1189
vnp = get_value_name(sg_lib_serv_in12_arr, service_action, peri_type);
1102
strncpy(buff, vnp->name, buff_len);
1191
my_snprintf(buff, buff_len, "%s", vnp->name);
1104
snprintf(buff, buff_len, "Service action in(12)=0x%x",
1193
my_snprintf(buff, buff_len, "Service action in(12)=0x%x",
1107
1196
case SG_SERVICE_ACTION_OUT_12:
1108
1197
vnp = get_value_name(sg_lib_serv_out12_arr, service_action, peri_type);
1110
strncpy(buff, vnp->name, buff_len);
1199
my_snprintf(buff, buff_len, "%s", vnp->name);
1112
snprintf(buff, buff_len, "Service action out(12)=0x%x",
1201
my_snprintf(buff, buff_len, "Service action out(12)=0x%x",
1115
1204
case SG_SERVICE_ACTION_IN_16:
1116
1205
vnp = get_value_name(sg_lib_serv_in16_arr, service_action, peri_type);
1118
strncpy(buff, vnp->name, buff_len);
1207
my_snprintf(buff, buff_len, "%s", vnp->name);
1120
snprintf(buff, buff_len, "Service action in(16)=0x%x",
1209
my_snprintf(buff, buff_len, "Service action in(16)=0x%x",
1123
1212
case SG_SERVICE_ACTION_OUT_16:
1124
1213
vnp = get_value_name(sg_lib_serv_out16_arr, service_action, peri_type);
1126
strncpy(buff, vnp->name, buff_len);
1215
my_snprintf(buff, buff_len, "%s", vnp->name);
1128
snprintf(buff, buff_len, "Service action out(16)=0x%x",
1217
my_snprintf(buff, buff_len, "Service action out(16)=0x%x",
1131
1220
case SG_PERSISTENT_RESERVE_IN:
1132
1221
vnp = get_value_name(sg_lib_pr_in_arr, service_action, peri_type);
1134
strncpy(buff, vnp->name, buff_len);
1223
my_snprintf(buff, buff_len, "%s", vnp->name);
1136
snprintf(buff, buff_len, "Persistent reserve in, service "
1137
"action=0x%x", service_action);
1225
my_snprintf(buff, buff_len, "Persistent reserve in, service "
1226
"action=0x%x", service_action);
1139
1228
case SG_PERSISTENT_RESERVE_OUT:
1140
1229
vnp = get_value_name(sg_lib_pr_out_arr, service_action, peri_type);
1142
strncpy(buff, vnp->name, buff_len);
1144
snprintf(buff, buff_len, "Persistent reserve out, service "
1145
"action=0x%x", service_action);
1231
my_snprintf(buff, buff_len, "%s", vnp->name);
1233
my_snprintf(buff, buff_len, "Persistent reserve out, service "
1234
"action=0x%x", service_action);
1236
case SG_EXTENDED_COPY:
1237
vnp = get_value_name(sg_lib_xcopy_sa_arr, service_action, peri_type);
1239
my_snprintf(buff, buff_len, "%s", vnp->name);
1241
my_snprintf(buff, buff_len, "Extended copy, service action=0x%x",
1244
case SG_RECEIVE_COPY:
1245
vnp = get_value_name(sg_lib_rec_copy_sa_arr, service_action,
1248
my_snprintf(buff, buff_len, "%s", vnp->name);
1250
my_snprintf(buff, buff_len, "Receive copy, service action=0x%x",
1253
case SG_READ_BUFFER:
1254
/* spc4r34 requested treating mode as service action */
1255
vnp = get_value_name(sg_lib_read_buff_arr, service_action,
1258
my_snprintf(buff, buff_len, "Read buffer (%s)\n", vnp->name);
1260
my_snprintf(buff, buff_len, "Read buffer, mode=0x%x",
1263
case SG_WRITE_BUFFER:
1264
/* spc4r34 requested treating mode as service action */
1265
vnp = get_value_name(sg_lib_write_buff_arr, service_action,
1268
my_snprintf(buff, buff_len, "Write buffer (%s)\n", vnp->name);
1270
my_snprintf(buff, buff_len, "Write buffer, mode=0x%x",
1148
1274
sg_get_opcode_name(cmd_byte0, peri_type, buff_len, buff);