diff --git a/scsiprint.cpp b/scsiprint.cpp
index cca0dcc..5f55265 100644
a
|
b
|
scsiGetSupportedLogPages(scsi_device * device)
|
126 | 126 | if ((err = scsiLogSense(device, SUPPORTED_LPAGES, 0, gBuf, |
127 | 127 | LOG_RESP_LEN, 0))) { |
128 | 128 | if (scsi_debugmode > 0) |
129 | | pout("%s for supported pages failed [%s]\n", logSenStr, |
| 129 | jout("%s for supported pages failed [%s]\n", logSenStr, |
130 | 130 | scsiErrString(err)); |
131 | 131 | /* try one more time with defined length, workaround for the bug #678 |
132 | 132 | found with ST8000NM0075/E001 */ |
133 | 133 | err = scsiLogSense(device, SUPPORTED_LPAGES, 0, gBuf, |
134 | 134 | LOG_RESP_LEN, 68); /* 64 max pages + 4b header */ |
135 | 135 | if (scsi_debugmode > 0) |
136 | | pout("%s for supported pages failed (second attempt) [%s]\n", |
| 136 | jout("%s for supported pages failed (second attempt) [%s]\n", |
137 | 137 | logSenStr, scsiErrString(err)); |
138 | 138 | if (err) |
139 | 139 | return; |
… |
… |
scsiGetSupportedLogPages(scsi_device * device)
|
146 | 146 | gBuf, LOG_RESP_LONG_LEN, |
147 | 147 | -1 /* just single not double fetch */))) { |
148 | 148 | if (scsi_debugmode > 0) |
149 | | pout("%s for supported pages and subpages failed [%s]\n", |
| 149 | jout("%s for supported pages and subpages failed [%s]\n", |
150 | 150 | logSenStr, scsiErrString(err)); |
151 | 151 | } else { |
152 | 152 | if (0 == memcmp(gBuf, sup_lpgs, LOG_RESP_LEN)) { |
153 | 153 | if (scsi_debugmode > 0) |
154 | | pout("%s: %s ignored subpage field, bad\n", |
| 154 | jout("%s: %s ignored subpage field, bad\n", |
155 | 155 | __func__, logSenRspStr); |
156 | 156 | } else if (! ((0x40 & gBuf[0]) && |
157 | 157 | (SUPP_SPAGE_L_SPAGE == gBuf[1]))) { |
158 | 158 | if (scsi_debugmode > 0) |
159 | | pout("%s supported subpages is bad SPF=%u SUBPG=%u\n", |
| 159 | jout("%s supported subpages is bad SPF=%u SUBPG=%u\n", |
160 | 160 | logSenRspStr, !! (0x40 & gBuf[0]), gBuf[2]); |
161 | 161 | } else |
162 | 162 | got_subpages = true; |
… |
… |
scsiGetSupportedLogPages(scsi_device * device)
|
185 | 185 | if (! ((NO_SUBPAGE_L_SPAGE == sub_pg_num) || |
186 | 186 | (SUPP_SPAGE_L_SPAGE == sub_pg_num))) { |
187 | 187 | if (scsi_debugmode > 1) |
188 | | pout("%s: Strange Log page number: 0x0,0x%x\n", |
| 188 | jout("%s: Strange Log page number: 0x0,0x%x\n", |
189 | 189 | __func__, sub_pg_num); |
190 | 190 | } |
191 | 191 | break; |
… |
… |
scsiGetSupportedLogPages(scsi_device * device)
|
284 | 284 | } |
285 | 285 | } |
286 | 286 | if (scsi_debugmode > 1) |
287 | | pout("%s: number of unreported (standard) log pages: %d (sub-pages: " |
| 287 | jout("%s: number of unreported (standard) log pages: %d (sub-pages: " |
288 | 288 | "%d)\n", __func__, num_unreported, num_unreported_spg); |
289 | 289 | } |
290 | 290 | |
… |
… |
scsiGetSmartData(scsi_device * device, bool attribs)
|
325 | 325 | |
326 | 326 | if (attribs && !gTempLPage) { |
327 | 327 | if (255 == currenttemp) |
328 | | pout("Current Drive Temperature: <not available>\n"); |
| 328 | jout("Current Drive Temperature: <not available>\n"); |
329 | 329 | else { |
330 | 330 | jout("Current Drive Temperature: %d C\n", currenttemp); |
331 | 331 | jglb["temperature"]["current"] = currenttemp; |
332 | 332 | } |
333 | 333 | if (255 == triptemp) |
334 | | pout("Drive Trip Temperature: <not available>\n"); |
335 | | else |
336 | | pout("Drive Trip Temperature: %d C\n", triptemp); |
| 334 | jout("Drive Trip Temperature: <not available>\n"); |
| 335 | else { |
| 336 | jout("Drive Trip Temperature: %d C\n", triptemp); |
| 337 | jglb["temperature"]["drive_trip"] = triptemp; |
| 338 | } |
337 | 339 | } |
338 | | pout("\n"); |
| 340 | jout("\n"); |
339 | 341 | return err; |
340 | 342 | } |
341 | 343 | |
… |
… |
scsiGetTapeAlertsData(scsi_device * device, int peripheral_type)
|
357 | 359 | print_on(); |
358 | 360 | if ((err = scsiLogSense(device, TAPE_ALERTS_LPAGE, 0, gBuf, |
359 | 361 | LOG_RESP_TAPE_ALERT_LEN, LOG_RESP_TAPE_ALERT_LEN))) { |
360 | | pout("%s Failed [%s]\n", __func__, scsiErrString(err)); |
| 362 | jout("%s Failed [%s]\n", __func__, scsiErrString(err)); |
361 | 363 | print_off(); |
362 | 364 | return -1; |
363 | 365 | } |
364 | 366 | if (gBuf[0] != 0x2e) { |
365 | | pout("TapeAlerts %s Failed\n", logSenStr); |
| 367 | jout("TapeAlerts %s Failed\n", logSenStr); |
366 | 368 | print_off(); |
367 | 369 | return -1; |
368 | 370 | } |
… |
… |
scsiGetTapeAlertsData(scsi_device * device, int peripheral_type)
|
378 | 380 | scsiTapeAlertsTapeDevice(parametercode); |
379 | 381 | if (*ts == *s) { |
380 | 382 | if (!failures) |
381 | | pout("TapeAlert Errors (C=Critical, W=Warning, " |
| 383 | jout("TapeAlert Errors (C=Critical, W=Warning, " |
382 | 384 | "I=Informational):\n"); |
383 | | pout("[0x%02x] %s\n", parametercode, ts); |
| 385 | jout("[0x%02x] %s\n", parametercode, ts); |
384 | 386 | failures += 1; |
385 | 387 | } |
386 | 388 | } |
… |
… |
scsiGetTapeAlertsData(scsi_device * device, int peripheral_type)
|
389 | 391 | print_off(); |
390 | 392 | |
391 | 393 | if (! failures) |
392 | | pout("TapeAlert: OK\n"); |
| 394 | jout("TapeAlert: OK\n"); |
393 | 395 | |
394 | 396 | return failures; |
395 | 397 | } |
… |
… |
scsiGetStartStopData(scsi_device * device)
|
403 | 405 | if ((err = scsiLogSense(device, STARTSTOP_CYCLE_COUNTER_LPAGE, 0, gBuf, |
404 | 406 | LOG_RESP_LEN, 0))) { |
405 | 407 | print_on(); |
406 | | pout("%s Failed [%s]\n", __func__, scsiErrString(err)); |
| 408 | jout("%s Failed [%s]\n", __func__, scsiErrString(err)); |
407 | 409 | print_off(); |
408 | 410 | return; |
409 | 411 | } |
410 | 412 | if ((gBuf[0] & 0x3f) != STARTSTOP_CYCLE_COUNTER_LPAGE) { |
411 | 413 | print_on(); |
412 | | pout("StartStop %s Failed, page mismatch\n", logSenStr); |
| 414 | jout("StartStop %s Failed, page mismatch\n", logSenStr); |
413 | 415 | print_off(); |
414 | 416 | return; |
415 | 417 | } |
… |
… |
scsiGetStartStopData(scsi_device * device)
|
418 | 420 | for (k = len; k > 0; k -= extra, ucp += extra) { |
419 | 421 | if (k < 3) { |
420 | 422 | print_on(); |
421 | | pout("StartStop %s: short\n", logSenRspStr); |
| 423 | jout("StartStop %s: short\n", logSenRspStr); |
422 | 424 | print_off(); |
423 | 425 | return; |
424 | 426 | } |
… |
… |
scsiGetStartStopData(scsi_device * device)
|
429 | 431 | switch (pc) { |
430 | 432 | case 1: |
431 | 433 | if (10 == extra) |
432 | | pout("Manufactured in week %.2s of year %.4s\n", ucp + 8, |
| 434 | jout("Manufactured in week %.2s of year %.4s\n", ucp + 8, |
433 | 435 | ucp + 4); |
434 | 436 | break; |
435 | 437 | case 2: |
… |
… |
scsiGetStartStopData(scsi_device * device)
|
437 | 439 | break; |
438 | 440 | case 3: |
439 | 441 | if ((extra > 7) && (! is_all_ffs)) |
440 | | pout("Specified cycle count over device lifetime: %u\n", u); |
| 442 | jout("Specified cycle count over device lifetime: %u\n", u); |
441 | 443 | break; |
442 | 444 | case 4: |
443 | 445 | if ((extra > 7) && (! is_all_ffs)) |
444 | | pout("Accumulated start-stop cycles: %u\n", u); |
| 446 | jout("Accumulated start-stop cycles: %u\n", u); |
445 | 447 | break; |
446 | 448 | case 5: |
447 | 449 | if ((extra > 7) && (! is_all_ffs)) |
448 | | pout("Specified load-unload count over device lifetime: " |
| 450 | jout("Specified load-unload count over device lifetime: " |
449 | 451 | "%u\n", u); |
450 | 452 | break; |
451 | 453 | case 6: |
452 | 454 | if ((extra > 7) && (! is_all_ffs)) |
453 | | pout("Accumulated load-unload cycles: %u\n", u); |
| 455 | jout("Accumulated load-unload cycles: %u\n", u); |
454 | 456 | break; |
455 | 457 | default: |
456 | 458 | /* ignore */ |
… |
… |
scsiPrintPendingDefectsLPage(scsi_device * device)
|
472 | 474 | PEND_DEFECTS_L_SPAGE, gBuf, LOG_RESP_LONG_LEN, |
473 | 475 | 0))) { |
474 | 476 | print_on(); |
475 | | pout("%s Failed [%s]\n", __func__, scsiErrString(err)); |
| 477 | jout("%s Failed [%s]\n", __func__, scsiErrString(err)); |
476 | 478 | print_off(); |
477 | 479 | return; |
478 | 480 | } |
479 | 481 | if (((gBuf[0] & 0x3f) != BACKGROUND_RESULTS_LPAGE) && |
480 | 482 | (gBuf[1] != PEND_DEFECTS_L_SPAGE)) { |
481 | 483 | print_on(); |
482 | | pout("%s %s, page mismatch\n", pDefStr, logSenRspStr); |
| 484 | jout("%s %s, page mismatch\n", pDefStr, logSenRspStr); |
483 | 485 | print_off(); |
484 | 486 | return; |
485 | 487 | } |
486 | 488 | num = sg_get_unaligned_be16(gBuf + 2); |
487 | 489 | if (num > LOG_RESP_LONG_LEN) { |
488 | 490 | print_on(); |
489 | | pout("%s %s too long\n", pDefStr, logSenRspStr); |
| 491 | jout("%s %s too long\n", pDefStr, logSenRspStr); |
490 | 492 | print_off(); |
491 | 493 | return; |
492 | 494 | } |
… |
… |
scsiPrintPendingDefectsLPage(scsi_device * device)
|
499 | 501 | printf(" Pending defect count:"); |
500 | 502 | if ((pl < 8) || (num < 8)) { |
501 | 503 | print_on(); |
502 | | pout("%s truncated descriptor\n", pDefStr); |
| 504 | jout("%s truncated descriptor\n", pDefStr); |
503 | 505 | print_off(); |
504 | 506 | return; |
505 | 507 | } |
… |
… |
scsiPrintPendingDefectsLPage(scsi_device * device)
|
517 | 519 | default: |
518 | 520 | if ((pl < 16) || (num < 16)) { |
519 | 521 | print_on(); |
520 | | pout("%s truncated descriptor\n", pDefStr); |
| 522 | jout("%s truncated descriptor\n", pDefStr); |
521 | 523 | print_off(); |
522 | 524 | return; |
523 | 525 | } |
… |
… |
scsiPrintGrownDefectListLen(scsi_device * device)
|
552 | 554 | if (err) { |
553 | 555 | if (scsi_debugmode > 0) { |
554 | 556 | print_on(); |
555 | | pout("%s (10) Failed: %s\n", hname, scsiErrString(err)); |
| 557 | jout("%s (10) Failed: %s\n", hname, scsiErrString(err)); |
556 | 558 | print_off(); |
557 | 559 | } |
558 | 560 | return; |
… |
… |
scsiPrintGrownDefectListLen(scsi_device * device)
|
563 | 565 | else { |
564 | 566 | if (scsi_debugmode > 0) { |
565 | 567 | print_on(); |
566 | | pout("%s (12) Failed: %s\n", hname, scsiErrString(err)); |
| 568 | jout("%s (12) Failed: %s\n", hname, scsiErrString(err)); |
567 | 569 | print_off(); |
568 | 570 | } |
569 | 571 | return; |
… |
… |
scsiPrintGrownDefectListLen(scsi_device * device)
|
575 | 577 | int generation = sg_get_unaligned_be16(gBuf + 2); |
576 | 578 | if ((generation > 1) && (scsi_debugmode > 0)) { |
577 | 579 | print_on(); |
578 | | pout("%s (12): generation=%d\n", hname, generation); |
| 580 | jout("%s (12): generation=%d\n", hname, generation); |
579 | 581 | print_off(); |
580 | 582 | } |
581 | 583 | dl_len = sg_get_unaligned_be32(gBuf + 4); |
… |
… |
scsiPrintGrownDefectListLen(scsi_device * device)
|
583 | 585 | dl_len = sg_get_unaligned_be16(gBuf + 2); |
584 | 586 | if (0x8 != (gBuf[1] & 0x18)) { |
585 | 587 | print_on(); |
586 | | pout("%s: asked for grown list but didn't get it\n", hname); |
| 588 | jout("%s: asked for grown list but didn't get it\n", hname); |
587 | 589 | print_off(); |
588 | 590 | return; |
589 | 591 | } |
… |
… |
scsiPrintGrownDefectListLen(scsi_device * device)
|
605 | 607 | break; |
606 | 608 | default: |
607 | 609 | print_on(); |
608 | | pout("defect list format %d unknown\n", dl_format); |
| 610 | jout("defect list format %d unknown\n", dl_format); |
609 | 611 | print_off(); |
610 | 612 | break; |
611 | 613 | } |
612 | | if (0 == dl_len) |
613 | | pout("Elements in grown defect list: 0\n\n"); |
| 614 | if (0 == dl_len) { |
| 615 | jout("Elements in grown defect list: 0\n\n"); |
| 616 | jglb["scsi_elements_grown_list"] = 0; |
| 617 | } |
614 | 618 | else { |
615 | 619 | if (0 == div) |
616 | | pout("Grown defect list length=%u bytes [unknown " |
| 620 | jout("Grown defect list length=%u bytes [unknown " |
617 | 621 | "number of elements]\n\n", dl_len); |
618 | | else |
619 | | pout("Elements in grown defect list: %u\n\n", dl_len / div); |
| 622 | else { |
| 623 | jout("Elements in grown defect list: %u\n\n", dl_len / div); |
| 624 | jglb["scsi_elements_grown_list"] = dl_len; |
| 625 | } |
620 | 626 | } |
621 | 627 | } |
622 | 628 | |
… |
… |
scsiPrintSeagateCacheLPage(scsi_device * device)
|
632 | 638 | LOG_RESP_LEN, 0))) { |
633 | 639 | if (scsi_debugmode > 0) { |
634 | 640 | print_on(); |
635 | | pout("%s %s Failed: %s\n", seaCacStr, logSenStr, |
| 641 | jout("%s %s Failed: %s\n", seaCacStr, logSenStr, |
636 | 642 | scsiErrString(err)); |
637 | 643 | print_off(); |
638 | 644 | } |
… |
… |
scsiPrintSeagateCacheLPage(scsi_device * device)
|
641 | 647 | if ((gBuf[0] & 0x3f) != SEAGATE_CACHE_LPAGE) { |
642 | 648 | if (scsi_debugmode > 0) { |
643 | 649 | print_on(); |
644 | | pout("%s %s, page mismatch\n", seaCacStr, logSenRspStr); |
| 650 | jout("%s %s, page mismatch\n", seaCacStr, logSenRspStr); |
645 | 651 | print_off(); |
646 | 652 | } |
647 | 653 | return; |
… |
… |
scsiPrintSeagateCacheLPage(scsi_device * device)
|
658 | 664 | default: |
659 | 665 | if (scsi_debugmode > 0) { |
660 | 666 | print_on(); |
661 | | pout("Vendor (%s) lpage has unexpected parameter, skip\n", |
| 667 | jout("Vendor (%s) lpage has unexpected parameter, skip\n", |
662 | 668 | seaCacStr); |
663 | 669 | print_off(); |
664 | 670 | } |
… |
… |
scsiPrintSeagateCacheLPage(scsi_device * device)
|
667 | 673 | num -= pl; |
668 | 674 | ucp += pl; |
669 | 675 | } |
670 | | pout("Vendor (%s) information\n", seaCacStr); |
| 676 | jout("Vendor (%s) information\n", seaCacStr); |
671 | 677 | num = len - 4; |
672 | 678 | ucp = &gBuf[0] + 4; |
673 | 679 | while (num > 3) { |
674 | 680 | pc = sg_get_unaligned_be16(ucp + 0); |
675 | 681 | pl = ucp[3] + 4; |
676 | 682 | switch (pc) { |
677 | | case 0: pout(" Blocks sent to initiator"); break; |
678 | | case 1: pout(" Blocks received from initiator"); break; |
679 | | case 2: pout(" Blocks read from cache and sent to initiator"); break; |
680 | | case 3: pout(" Number of read and write commands whose size " |
| 683 | case 0: jout(" Blocks sent to initiator"); break; |
| 684 | case 1: jout(" Blocks received from initiator"); break; |
| 685 | case 2: jout(" Blocks read from cache and sent to initiator"); break; |
| 686 | case 3: jout(" Number of read and write commands whose size " |
681 | 687 | "<= segment size"); break; |
682 | | case 4: pout(" Number of read and write commands whose size " |
| 688 | case 4: jout(" Number of read and write commands whose size " |
683 | 689 | "> segment size"); break; |
684 | | default: pout(" Unknown Seagate parameter code [0x%x]", pc); break; |
| 690 | default: jout(" Unknown Seagate parameter code [0x%x]", pc); break; |
685 | 691 | } |
686 | 692 | int k = pl - 4; |
687 | 693 | const int sz_ull = (int)sizeof(ull); |
… |
… |
scsiPrintSeagateCacheLPage(scsi_device * device)
|
691 | 697 | k = sz_ull; |
692 | 698 | } |
693 | 699 | ull = sg_get_unaligned_be(k, xp + 0); |
694 | | pout(" = %" PRIu64 "\n", ull); |
| 700 | jout(" = %" PRIu64 "\n", ull); |
695 | 701 | num -= pl; |
696 | 702 | ucp += pl; |
697 | 703 | } |
698 | | pout("\n"); |
| 704 | jout("\n"); |
699 | 705 | } |
700 | 706 | |
701 | 707 | static void |
… |
… |
scsiPrintSeagateFactoryLPage(scsi_device * device)
|
704 | 710 | int num, pl, pc, len, err, good, bad; |
705 | 711 | unsigned char * ucp; |
706 | 712 | uint64_t ull; |
| 713 | static const char * jname = "format_status"; |
707 | 714 | |
708 | 715 | if ((err = scsiLogSense(device, SEAGATE_FACTORY_LPAGE, 0, gBuf, |
709 | 716 | LOG_RESP_LEN, 0))) { |
710 | 717 | if (scsi_debugmode > 0) { |
711 | 718 | print_on(); |
712 | | pout("%s Failed [%s]\n", __func__, scsiErrString(err)); |
| 719 | jout("%s Failed [%s]\n", __func__, scsiErrString(err)); |
713 | 720 | print_off(); |
714 | 721 | } |
715 | 722 | return; |
… |
… |
scsiPrintSeagateFactoryLPage(scsi_device * device)
|
717 | 724 | if ((gBuf[0] & 0x3f) != SEAGATE_FACTORY_LPAGE) { |
718 | 725 | if (scsi_debugmode > 0) { |
719 | 726 | print_on(); |
720 | | pout("Seagate/Hitachi Factory %s, page mismatch\n", logSenRspStr); |
| 727 | jout("Seagate/Hitachi Factory %s, page mismatch\n", logSenRspStr); |
721 | 728 | print_off(); |
722 | 729 | } |
723 | 730 | return; |
… |
… |
scsiPrintSeagateFactoryLPage(scsi_device * device)
|
744 | 751 | if ((good < 2) || (bad > 4)) { /* heuristic */ |
745 | 752 | if (scsi_debugmode > 0) { |
746 | 753 | print_on(); |
747 | | pout("\nVendor (Seagate/Hitachi) factory lpage has too many " |
| 754 | jout("\nVendor (Seagate/Hitachi) factory lpage has too many " |
748 | 755 | "unexpected parameters, skip\n"); |
749 | 756 | print_off(); |
750 | 757 | } |
751 | 758 | return; |
752 | 759 | } |
753 | | pout("Vendor (Seagate/Hitachi) factory information\n"); |
| 760 | jout("Vendor (Seagate/Hitachi) factory information\n"); |
754 | 761 | num = len - 4; |
755 | 762 | ucp = &gBuf[0] + 4; |
756 | 763 | while (num > 3) { |
… |
… |
scsiPrintSeagateFactoryLPage(scsi_device * device)
|
758 | 765 | pl = ucp[3] + 4; |
759 | 766 | good = 0; |
760 | 767 | switch (pc) { |
761 | | case 0: pout(" number of hours powered up"); |
| 768 | case 0: jout(" number of hours powered up"); |
| 769 | jname = "scsi_hours_powered_up"; |
762 | 770 | good = 1; |
763 | 771 | break; |
764 | | case 8: pout(" number of minutes until next internal SMART test"); |
| 772 | case 8: jout(" number of minutes until next internal SMART test"); |
| 773 | jname = "scsi_minutes_next_smart_test"; |
765 | 774 | good = 1; |
766 | 775 | break; |
767 | 776 | default: |
768 | 777 | if (scsi_debugmode > 0) { |
769 | 778 | print_on(); |
770 | | pout("Vendor (Seagate/Hitachi) factory lpage: " |
| 779 | jout("Vendor (Seagate/Hitachi) factory lpage: " |
771 | 780 | "unknown parameter code [0x%x]\n", pc); |
772 | 781 | print_off(); |
773 | 782 | } |
… |
… |
scsiPrintSeagateFactoryLPage(scsi_device * device)
|
781 | 790 | k = (int)sizeof(ull); |
782 | 791 | } |
783 | 792 | ull = sg_get_unaligned_be(k, xp + 0); |
784 | | if (0 == pc) |
785 | | pout(" = %.2f\n", ull / 60.0 ); |
786 | | else |
787 | | pout(" = %" PRIu64 "\n", ull); |
| 793 | if (0 == pc) { |
| 794 | jout(" = %.2f\n", ull / 60.0 ); |
| 795 | jglb[jname] = strprintf("%.2f", ull / 60.0); |
| 796 | } |
| 797 | else { |
| 798 | jout(" = %" PRIu64 "\n", ull); |
| 799 | jglb[jname] = ull; |
| 800 | } |
788 | 801 | } |
789 | 802 | num -= pl; |
790 | 803 | ucp += pl; |
791 | 804 | } |
792 | | pout("\n"); |
| 805 | jout("\n"); |
793 | 806 | } |
794 | 807 | |
795 | 808 | static void |
… |
… |
scsiPrintErrorCounterLog(scsi_device * device)
|
821 | 834 | } |
822 | 835 | } |
823 | 836 | if (found[0] || found[1] || found[2]) { |
824 | | pout("Error counter log:\n"); |
825 | | pout(" Errors Corrected by Total " |
| 837 | jout("Error counter log:\n"); |
| 838 | jout(" Errors Corrected by Total " |
826 | 839 | "Correction Gigabytes Total\n"); |
827 | | pout(" ECC rereads/ errors " |
| 840 | jout(" ECC rereads/ errors " |
828 | 841 | "algorithm processed uncorrected\n"); |
829 | | pout(" fast | delayed rewrites corrected " |
| 842 | jout(" fast | delayed rewrites corrected " |
830 | 843 | "invocations [10^9 bytes] errors\n"); |
| 844 | |
| 845 | json::ref jref = jglb["scsi_error_counter_log"]; |
831 | 846 | for (int k = 0; k < 3; ++k) { |
832 | 847 | if (! found[k]) |
833 | 848 | continue; |
834 | 849 | ecp = &errCounterArr[k]; |
835 | 850 | static const char * const pageNames[3] = |
836 | 851 | {"read: ", "write: ", "verify: "}; |
837 | | pout("%s%8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64 |
| 852 | static const char * jpageNames[3] = |
| 853 | {"read", "write", "verify"}; |
| 854 | jout("%s%8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64 |
838 | 855 | " %8" PRIu64, pageNames[k], ecp->counter[0], |
839 | 856 | ecp->counter[1], ecp->counter[2], ecp->counter[3], |
840 | 857 | ecp->counter[4]); |
841 | 858 | double processed_gb = ecp->counter[5] / 1000000000.0; |
842 | | pout(" %12.3f %8" PRIu64 "\n", processed_gb, |
| 859 | jout(" %12.3f %8" PRIu64 "\n", processed_gb, |
843 | 860 | ecp->counter[6]); |
| 861 | // Error counter log info |
| 862 | jref[jpageNames[k]]["errors_corrected_by_eccfast"] = ecp->counter[0]; |
| 863 | jref[jpageNames[k]]["errors_corrected_by_eccdelayed"] = ecp->counter[1]; |
| 864 | jref[jpageNames[k]]["errors_corrected_by_rereads_rewrites"] = ecp->counter[2]; |
| 865 | jref[jpageNames[k]]["total_errors_corrected"] = ecp->counter[3]; |
| 866 | jref[jpageNames[k]]["correction_algorithm_invocations"] = ecp->counter[4]; |
| 867 | jref[jpageNames[k]]["gigabytes_processed"] = strprintf("%.3f", processed_gb); |
| 868 | jref[jpageNames[k]]["total_uncorrected_errors"] = ecp->counter[6]; |
844 | 869 | } |
845 | 870 | } |
846 | 871 | else |
847 | | pout("Error Counter logging not supported\n"); |
| 872 | jout("Error Counter logging not supported\n"); |
848 | 873 | if (gNonMediumELPage && (0 == scsiLogSense(device, |
849 | 874 | NON_MEDIUM_ERROR_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) { |
850 | 875 | struct scsiNonMediumError nme; |
851 | 876 | scsiDecodeNonMediumErrPage(gBuf, &nme); |
852 | 877 | if (nme.gotPC0) |
853 | | pout("\nNon-medium error count: %8" PRIu64 "\n", nme.counterPC0); |
| 878 | jout("\nNon-medium error count: %8" PRIu64 "\n", nme.counterPC0); |
854 | 879 | if (nme.gotTFE_H) |
855 | | pout("Track following error count [Hitachi]: %8" PRIu64 "\n", |
| 880 | jout("Track following error count [Hitachi]: %8" PRIu64 "\n", |
856 | 881 | nme.counterTFE_H); |
857 | 882 | if (nme.gotPE_H) |
858 | | pout("Positioning error count [Hitachi]: %8" PRIu64 "\n", |
| 883 | jout("Positioning error count [Hitachi]: %8" PRIu64 "\n", |
859 | 884 | nme.counterPE_H); |
860 | 885 | } |
861 | 886 | if (gLastNErrorEvLPage && |
… |
… |
scsiPrintErrorCounterLog(scsi_device * device)
|
868 | 893 | unsigned char * ucp = gBuf + 4; |
869 | 894 | num -= 4; |
870 | 895 | if (num < 4) |
871 | | pout("\nNo error events logged\n"); |
| 896 | jout("\nNo error events logged\n"); |
872 | 897 | else { |
873 | | pout("\nLast n error events log page\n"); |
| 898 | jout("\nLast n error events log page\n"); |
874 | 899 | for (int k = num, pl; k > 0; k -= pl, ucp += pl) { |
875 | 900 | if (k < 3) { |
876 | | pout(" <<short Last n error events log page>>\n"); |
| 901 | jout(" <<short Last n error events log page>>\n"); |
877 | 902 | break; |
878 | 903 | } |
879 | 904 | pl = ucp[3] + 4; |
880 | 905 | int pc = sg_get_unaligned_be16(ucp + 0); |
881 | 906 | if (pl > 4) { |
882 | 907 | if ((ucp[2] & 0x1) && (ucp[2] & 0x2)) { |
883 | | pout(" Error event %d:\n", pc); |
884 | | pout(" [binary]:\n"); |
| 908 | jout(" Error event %d:\n", pc); |
| 909 | jout(" [binary]:\n"); |
885 | 910 | dStrHex((const uint8_t *)ucp + 4, pl - 4, 1); |
886 | 911 | } else if (ucp[2] & 0x1) { |
887 | | pout(" Error event %d:\n", pc); |
888 | | pout(" %.*s\n", pl - 4, (const char *)(ucp + 4)); |
| 912 | jout(" Error event %d:\n", pc); |
| 913 | jout(" %.*s\n", pl - 4, (const char *)(ucp + 4)); |
889 | 914 | } else { |
890 | 915 | if (scsi_debugmode > 0) { |
891 | | pout(" Error event %d:\n", pc); |
892 | | pout(" [data counter??]:\n"); |
| 916 | jout(" Error event %d:\n", pc); |
| 917 | jout(" [data counter??]:\n"); |
893 | 918 | dStrHex((const uint8_t *)ucp + 4, pl - 4, 1); |
894 | 919 | } |
895 | 920 | } |
896 | 921 | } |
897 | 922 | } |
898 | 923 | if (truncated) |
899 | | pout(" >>>> log truncated, fetched %d of %d available " |
| 924 | jout(" >>>> log truncated, fetched %d of %d available " |
900 | 925 | "bytes\n", LOG_RESP_LONG_LEN, truncated); |
901 | 926 | } |
902 | 927 | } |
903 | | pout("\n"); |
| 928 | jout("\n"); |
904 | 929 | } |
905 | 930 | |
906 | 931 | static const char * self_test_code[] = { |
… |
… |
scsiPrintSelfTest(scsi_device * device)
|
952 | 977 | if (!scsiRequestSense(device, &sense_info) && |
953 | 978 | (sense_info.asc == 0x04 && sense_info.ascq == 0x09 && |
954 | 979 | sense_info.progress != -1)) { |
955 | | pout("%s execution status:\t\t%d%% of test remaining\n", hname, |
| 980 | jout("%s execution status:\t\t%d%% of test remaining\n", hname, |
956 | 981 | 100 - ((sense_info.progress * 100) / 65535)); |
957 | 982 | } |
958 | 983 | |
959 | 984 | if ((err = scsiLogSense(device, SELFTEST_RESULTS_LPAGE, 0, gBuf, |
960 | 985 | LOG_RESP_SELF_TEST_LEN, 0))) { |
961 | 986 | print_on(); |
962 | | pout("%s: Failed [%s]\n", __func__, scsiErrString(err)); |
| 987 | jout("%s: Failed [%s]\n", __func__, scsiErrString(err)); |
963 | 988 | print_off(); |
964 | 989 | return FAILSMART; |
965 | 990 | } |
966 | 991 | if ((gBuf[0] & 0x3f) != SELFTEST_RESULTS_LPAGE) { |
967 | 992 | print_on(); |
968 | | pout("%s %s, page mismatch\n", hname, logSenRspStr); |
| 993 | jout("%s %s, page mismatch\n", hname, logSenRspStr); |
969 | 994 | print_off(); |
970 | 995 | return FAILSMART; |
971 | 996 | } |
… |
… |
scsiPrintSelfTest(scsi_device * device)
|
974 | 999 | // Log sense page length 0x190 bytes |
975 | 1000 | if (num != 0x190) { |
976 | 1001 | print_on(); |
977 | | pout("%s %s length is 0x%x not 0x190 bytes\n", hname, logSenStr, num); |
| 1002 | jout("%s %s length is 0x%x not 0x190 bytes\n", hname, logSenStr, num); |
978 | 1003 | print_off(); |
979 | 1004 | return FAILSMART; |
980 | 1005 | } |
… |
… |
scsiPrintSelfTest(scsi_device * device)
|
990 | 1015 | |
991 | 1016 | // only print header if needed |
992 | 1017 | if (noheader) { |
993 | | pout("SMART %s log\n", hname); |
994 | | pout("Num Test Status segment " |
| 1018 | jout("SMART %s log\n", hname); |
| 1019 | jout("Num Test Status segment " |
995 | 1020 | "LifeTime LBA_first_err [SK ASC ASQ]\n"); |
996 | | pout(" Description number " |
| 1021 | jout(" Description number " |
997 | 1022 | "(hours)\n"); |
998 | 1023 | noheader=0; |
999 | 1024 | } |
1000 | 1025 | |
1001 | 1026 | // print parameter code (test number) & self-test code text |
1002 | | pout("#%2d %s", sg_get_unaligned_be16(ucp + 0), |
| 1027 | jout("#%2d %s", sg_get_unaligned_be16(ucp + 0), |
1003 | 1028 | self_test_code[(ucp[4] >> 5) & 0x7]); |
1004 | 1029 | |
1005 | 1030 | // check the self-test result nibble, using the self-test results |
… |
… |
scsiPrintSelfTest(scsi_device * device)
|
1035 | 1060 | default: |
1036 | 1061 | break; |
1037 | 1062 | } |
1038 | | pout(" %s", self_test_result[res]); |
| 1063 | jout(" %s", self_test_result[res]); |
1039 | 1064 | |
1040 | 1065 | // self-test number identifies test that failed and consists |
1041 | 1066 | // of either the number of the segment that failed during |
… |
… |
scsiPrintSelfTest(scsi_device * device)
|
1044 | 1069 | // vendor-specific method of putting both numbers into a |
1045 | 1070 | // single byte. |
1046 | 1071 | if (ucp[5]) |
1047 | | pout(" %3d", (int)ucp[5]); |
| 1072 | jout(" %3d", (int)ucp[5]); |
1048 | 1073 | else |
1049 | | pout(" -"); |
| 1074 | jout(" -"); |
1050 | 1075 | |
1051 | 1076 | // print time that the self-test was completed |
1052 | 1077 | if (n==0 && res==0xf) |
1053 | 1078 | // self-test in progress |
1054 | | pout(" NOW"); |
| 1079 | jout(" NOW"); |
1055 | 1080 | else |
1056 | | pout(" %5d", n); |
| 1081 | jout(" %5d", n); |
1057 | 1082 | |
1058 | 1083 | // construct 8-byte integer address of first failure |
1059 | 1084 | ull = sg_get_unaligned_be64(ucp + 8); |
… |
… |
scsiPrintSelfTest(scsi_device * device)
|
1065 | 1090 | // was hex but change to decimal to conform with ATA |
1066 | 1091 | snprintf(buff, sizeof(buff), "%" PRIu64, ull); |
1067 | 1092 | // snprintf(buff, sizeof(buff), "0x%" PRIx64, ull); |
1068 | | pout("%18s", buff); |
| 1093 | jout("%18s", buff); |
1069 | 1094 | } else |
1070 | | pout(" -"); |
| 1095 | jout(" -"); |
1071 | 1096 | |
1072 | 1097 | // if sense key nonzero, then print it, along with |
1073 | 1098 | // additional sense code and additional sense code qualifier |
1074 | 1099 | if (ucp[16] & 0xf) |
1075 | | pout(" [0x%x 0x%x 0x%x]\n", ucp[16] & 0xf, ucp[17], ucp[18]); |
| 1100 | jout(" [0x%x 0x%x 0x%x]\n", ucp[16] & 0xf, ucp[17], ucp[18]); |
1076 | 1101 | else |
1077 | | pout(" [- - -]\n"); |
| 1102 | jout(" [- - -]\n"); |
1078 | 1103 | } |
1079 | 1104 | |
1080 | 1105 | // if header never printed, then there was no output |
1081 | 1106 | if (noheader) |
1082 | | pout("No %ss have been logged\n", hname); |
| 1107 | jout("No %ss have been logged\n", hname); |
1083 | 1108 | else |
1084 | 1109 | if ((0 == scsiFetchExtendedSelfTestTime(device, &durationSec, |
1085 | 1110 | modese_len)) && (durationSec > 0)) { |
1086 | | pout("\nLong (extended) %s duration: %d seconds " |
| 1111 | jout("\nLong (extended) %s duration: %d seconds " |
1087 | 1112 | "[%.1f minutes]\n", hname, durationSec, durationSec / 60.0); |
1088 | 1113 | } |
1089 | | pout("\n"); |
| 1114 | jout("\n"); |
1090 | 1115 | return retval; |
1091 | 1116 | } |
1092 | 1117 | |
… |
… |
scsiPrintBackgroundResults(scsi_device * device)
|
1131 | 1156 | if ((err = scsiLogSense(device, BACKGROUND_RESULTS_LPAGE, 0, gBuf, |
1132 | 1157 | LOG_RESP_LONG_LEN, 0))) { |
1133 | 1158 | print_on(); |
1134 | | pout("%s Failed [%s]\n", __func__, scsiErrString(err)); |
| 1159 | jout("%s Failed [%s]\n", __func__, scsiErrString(err)); |
1135 | 1160 | print_off(); |
1136 | 1161 | return FAILSMART; |
1137 | 1162 | } |
1138 | 1163 | if ((gBuf[0] & 0x3f) != BACKGROUND_RESULTS_LPAGE) { |
1139 | 1164 | print_on(); |
1140 | | pout("%s %s, page mismatch\n", hname, logSenRspStr); |
| 1165 | jout("%s %s, page mismatch\n", hname, logSenRspStr); |
1141 | 1166 | print_off(); |
1142 | 1167 | return FAILSMART; |
1143 | 1168 | } |
… |
… |
scsiPrintBackgroundResults(scsi_device * device)
|
1145 | 1170 | num = sg_get_unaligned_be16(gBuf + 2) + 4; |
1146 | 1171 | if (num < 20) { |
1147 | 1172 | print_on(); |
1148 | | pout("%s %s length is %d, no scan status\n", hname, logSenStr, num); |
| 1173 | jout("%s %s length is %d, no scan status\n", hname, logSenStr, num); |
1149 | 1174 | print_off(); |
1150 | 1175 | return FAILSMART; |
1151 | 1176 | } |
… |
… |
scsiPrintBackgroundResults(scsi_device * device)
|
1162 | 1187 | case 0: |
1163 | 1188 | if (noheader) { |
1164 | 1189 | noheader = 0; |
1165 | | pout("%s log\n", hname); |
| 1190 | jout("%s log\n", hname); |
1166 | 1191 | } |
1167 | | pout(" Status: "); |
| 1192 | jout(" Status: "); |
1168 | 1193 | if ((pl < 16) || (num < 16)) { |
1169 | | pout("\n"); |
| 1194 | jout("\n"); |
1170 | 1195 | break; |
1171 | 1196 | } |
1172 | 1197 | j = ucp[9]; |
1173 | 1198 | if (j < (int)(sizeof(bms_status) / sizeof(bms_status[0]))) |
1174 | | pout("%s\n", bms_status[j]); |
| 1199 | jout("%s\n", bms_status[j]); |
1175 | 1200 | else |
1176 | | pout("unknown [0x%x] background scan status value\n", j); |
| 1201 | jout("unknown [0x%x] background scan status value\n", j); |
1177 | 1202 | j = sg_get_unaligned_be32(ucp + 4); |
1178 | | pout(" Accumulated power on time, hours:minutes %d:%02d " |
| 1203 | jout(" Accumulated power on time, hours:minutes %d:%02d " |
1179 | 1204 | "[%d minutes]\n", (j / 60), (j % 60), j); |
1180 | | pout(" Number of background scans performed: %d, ", |
| 1205 | jglb["scsi_accumulated_power_on_time_minutes"] = j; |
| 1206 | jout(" Number of background scans performed: %d, ", |
1181 | 1207 | sg_get_unaligned_be16(ucp + 10)); |
1182 | | pout("scan progress: %.2f%%\n", |
| 1208 | jglb["scsi_number_sacns_performed"] = sg_get_unaligned_be16(ucp + 10); |
| 1209 | jout("scan progress: %.2f%%\n", |
1183 | 1210 | (double)sg_get_unaligned_be16(ucp + 12) * 100.0 / 65536.0); |
1184 | | pout(" Number of background medium scans performed: %d\n", |
| 1211 | jout(" Number of background medium scans performed: %d\n", |
1185 | 1212 | sg_get_unaligned_be16(ucp + 14)); |
| 1213 | jglb["scsi_number_medium_scans_performed"] = sg_get_unaligned_be16(ucp + 14); |
1186 | 1214 | break; |
1187 | 1215 | default: |
1188 | 1216 | if (noheader) { |
1189 | 1217 | noheader = 0; |
1190 | | pout("\n%s log\n", hname); |
| 1218 | jout("\n%s log\n", hname); |
1191 | 1219 | } |
1192 | 1220 | if (firstresult) { |
1193 | 1221 | firstresult = 0; |
1194 | | pout("\n # when lba(hex) [sk,asc,ascq] " |
| 1222 | jout("\n # when lba(hex) [sk,asc,ascq] " |
1195 | 1223 | "reassign_status\n"); |
1196 | 1224 | } |
1197 | | pout(" %3d ", pc); |
| 1225 | jout(" %3d ", pc); |
1198 | 1226 | if ((pl < 24) || (num < 24)) { |
1199 | 1227 | if (pl < 24) |
1200 | | pout("parameter length >= 24 expected, got %d\n", pl); |
| 1228 | jout("parameter length >= 24 expected, got %d\n", pl); |
1201 | 1229 | break; |
1202 | 1230 | } |
1203 | 1231 | j = sg_get_unaligned_be32(ucp + 4); |
1204 | | pout("%4d:%02d ", (j / 60), (j % 60)); |
| 1232 | jout("%4d:%02d ", (j / 60), (j % 60)); |
1205 | 1233 | for (m = 0; m < 8; ++m) |
1206 | | pout("%02x", ucp[16 + m]); |
1207 | | pout(" [%x,%x,%x] ", ucp[8] & 0xf, ucp[9], ucp[10]); |
| 1234 | jout("%02x", ucp[16 + m]); |
| 1235 | jout(" [%x,%x,%x] ", ucp[8] & 0xf, ucp[9], ucp[10]); |
1208 | 1236 | j = (ucp[8] >> 4) & 0xf; |
1209 | 1237 | if (j < |
1210 | 1238 | (int)(sizeof(reassign_status) / sizeof(reassign_status[0]))) |
1211 | | pout("%s\n", reassign_status[j]); |
| 1239 | jout("%s\n", reassign_status[j]); |
1212 | 1240 | else |
1213 | | pout("Reassign status: reserved [0x%x]\n", j); |
| 1241 | jout("Reassign status: reserved [0x%x]\n", j); |
1214 | 1242 | break; |
1215 | 1243 | } |
1216 | 1244 | num -= pl; |
1217 | 1245 | ucp += pl; |
1218 | 1246 | } |
1219 | 1247 | if (truncated) |
1220 | | pout(" >>>> log truncated, fetched %d of %d available " |
| 1248 | jout(" >>>> log truncated, fetched %d of %d available " |
1221 | 1249 | "bytes\n", LOG_RESP_LONG_LEN, truncated); |
1222 | | pout("\n"); |
| 1250 | jout("\n"); |
1223 | 1251 | return retval; |
1224 | 1252 | } |
1225 | 1253 | |
… |
… |
scsiPrintSSMedia(scsi_device * device)
|
1238 | 1266 | if ((err = scsiLogSense(device, SS_MEDIA_LPAGE, 0, gBuf, |
1239 | 1267 | LOG_RESP_LONG_LEN, 0))) { |
1240 | 1268 | print_on(); |
1241 | | pout("%s: Failed [%s]\n", __func__, scsiErrString(err)); |
| 1269 | jout("%s: Failed [%s]\n", __func__, scsiErrString(err)); |
1242 | 1270 | print_off(); |
1243 | 1271 | return FAILSMART; |
1244 | 1272 | } |
1245 | 1273 | if ((gBuf[0] & 0x3f) != SS_MEDIA_LPAGE) { |
1246 | 1274 | print_on(); |
1247 | | pout("%s %s, page mismatch\n", hname, logSenStr); |
| 1275 | jout("%s %s, page mismatch\n", hname, logSenStr); |
1248 | 1276 | print_off(); |
1249 | 1277 | return FAILSMART; |
1250 | 1278 | } |
… |
… |
scsiPrintSSMedia(scsi_device * device)
|
1252 | 1280 | num = sg_get_unaligned_be16(gBuf + 2) + 4; |
1253 | 1281 | if (num < 12) { |
1254 | 1282 | print_on(); |
1255 | | pout("%s %s length is %d, too short\n", hname, logSenStr, num); |
| 1283 | jout("%s %s length is %d, too short\n", hname, logSenStr, num); |
1256 | 1284 | print_off(); |
1257 | 1285 | return FAILSMART; |
1258 | 1286 | } |
… |
… |
scsiPrintSSMedia(scsi_device * device)
|
1269 | 1297 | case 1: |
1270 | 1298 | if (pl < 8) { |
1271 | 1299 | print_on(); |
1272 | | pout("%s Percentage used endurance indicator parameter " |
| 1300 | jout("%s Percentage used endurance indicator parameter " |
1273 | 1301 | "too short (pl=%d)\n", hname, pl); |
1274 | 1302 | print_off(); |
1275 | 1303 | return FAILSMART; |
1276 | 1304 | } |
1277 | | pout("Percentage used endurance indicator: %d%%\n", ucp[7]); |
| 1305 | jout("Percentage used endurance indicator: %d%%\n", ucp[7]); |
| 1306 | jglb["scsi_percentage_used_endurance_indicator"] = ucp[7]; |
1278 | 1307 | default: /* ignore other parameter codes */ |
1279 | 1308 | break; |
1280 | 1309 | } |
… |
… |
scsiPrintFormatStatus(scsi_device * device)
|
1366 | 1395 | break; |
1367 | 1396 | default: |
1368 | 1397 | if (scsi_debugmode > 3) { |
1369 | | pout(" Unknown Format parameter code = 0x%x\n", pc); |
| 1398 | jout(" Unknown Format parameter code = 0x%x\n", pc); |
1370 | 1399 | dStrHex((const uint8_t *)ucp, pl, 0); |
1371 | 1400 | } |
1372 | 1401 | is_count = false; |
… |
… |
show_sas_phy_event_info(int peis, unsigned int val, unsigned thresh_val)
|
1402 | 1431 | |
1403 | 1432 | switch (peis) { |
1404 | 1433 | case 0: |
1405 | | pout(" No event\n"); |
| 1434 | jout(" No event\n"); |
1406 | 1435 | break; |
1407 | 1436 | case 0x1: |
1408 | | pout(" Invalid word count: %u\n", val); |
| 1437 | jout(" Invalid word count: %u\n", val); |
1409 | 1438 | break; |
1410 | 1439 | case 0x2: |
1411 | | pout(" Running disparity error count: %u\n", val); |
| 1440 | jout(" Running disparity error count: %u\n", val); |
1412 | 1441 | break; |
1413 | 1442 | case 0x3: |
1414 | | pout(" Loss of dword synchronization count: %u\n", val); |
| 1443 | jout(" Loss of dword synchronization count: %u\n", val); |
1415 | 1444 | break; |
1416 | 1445 | case 0x4: |
1417 | | pout(" Phy reset problem count: %u\n", val); |
| 1446 | jout(" Phy reset problem count: %u\n", val); |
1418 | 1447 | break; |
1419 | 1448 | case 0x5: |
1420 | | pout(" Elasticity buffer overflow count: %u\n", val); |
| 1449 | jout(" Elasticity buffer overflow count: %u\n", val); |
1421 | 1450 | break; |
1422 | 1451 | case 0x6: |
1423 | | pout(" Received ERROR count: %u\n", val); |
| 1452 | jout(" Received ERROR count: %u\n", val); |
1424 | 1453 | break; |
1425 | 1454 | case 0x20: |
1426 | | pout(" Received address frame error count: %u\n", val); |
| 1455 | jout(" Received address frame error count: %u\n", val); |
1427 | 1456 | break; |
1428 | 1457 | case 0x21: |
1429 | | pout(" Transmitted abandon-class OPEN_REJECT count: %u\n", val); |
| 1458 | jout(" Transmitted abandon-class OPEN_REJECT count: %u\n", val); |
1430 | 1459 | break; |
1431 | 1460 | case 0x22: |
1432 | | pout(" Received abandon-class OPEN_REJECT count: %u\n", val); |
| 1461 | jout(" Received abandon-class OPEN_REJECT count: %u\n", val); |
1433 | 1462 | break; |
1434 | 1463 | case 0x23: |
1435 | | pout(" Transmitted retry-class OPEN_REJECT count: %u\n", val); |
| 1464 | jout(" Transmitted retry-class OPEN_REJECT count: %u\n", val); |
1436 | 1465 | break; |
1437 | 1466 | case 0x24: |
1438 | | pout(" Received retry-class OPEN_REJECT count: %u\n", val); |
| 1467 | jout(" Received retry-class OPEN_REJECT count: %u\n", val); |
1439 | 1468 | break; |
1440 | 1469 | case 0x25: |
1441 | | pout(" Received AIP (WATING ON PARTIAL) count: %u\n", val); |
| 1470 | jout(" Received AIP (WATING ON PARTIAL) count: %u\n", val); |
1442 | 1471 | break; |
1443 | 1472 | case 0x26: |
1444 | | pout(" Received AIP (WAITING ON CONNECTION) count: %u\n", val); |
| 1473 | jout(" Received AIP (WAITING ON CONNECTION) count: %u\n", val); |
1445 | 1474 | break; |
1446 | 1475 | case 0x27: |
1447 | | pout(" Transmitted BREAK count: %u\n", val); |
| 1476 | jout(" Transmitted BREAK count: %u\n", val); |
1448 | 1477 | break; |
1449 | 1478 | case 0x28: |
1450 | | pout(" Received BREAK count: %u\n", val); |
| 1479 | jout(" Received BREAK count: %u\n", val); |
1451 | 1480 | break; |
1452 | 1481 | case 0x29: |
1453 | | pout(" Break timeout count: %u\n", val); |
| 1482 | jout(" Break timeout count: %u\n", val); |
1454 | 1483 | break; |
1455 | 1484 | case 0x2a: |
1456 | | pout(" Connection count: %u\n", val); |
| 1485 | jout(" Connection count: %u\n", val); |
1457 | 1486 | break; |
1458 | 1487 | case 0x2b: |
1459 | | pout(" Peak transmitted pathway blocked count: %u\n", |
| 1488 | jout(" Peak transmitted pathway blocked count: %u\n", |
1460 | 1489 | val & 0xff); |
1461 | | pout(" Peak value detector threshold: %u\n", |
| 1490 | jout(" Peak value detector threshold: %u\n", |
1462 | 1491 | thresh_val & 0xff); |
1463 | 1492 | break; |
1464 | 1493 | case 0x2c: |
1465 | 1494 | u = val & 0xffff; |
1466 | 1495 | if (u < 0x8000) |
1467 | | pout(" Peak transmitted arbitration wait time (us): " |
| 1496 | jout(" Peak transmitted arbitration wait time (us): " |
1468 | 1497 | "%u\n", u); |
1469 | 1498 | else |
1470 | | pout(" Peak transmitted arbitration wait time (ms): " |
| 1499 | jout(" Peak transmitted arbitration wait time (ms): " |
1471 | 1500 | "%u\n", 33 + (u - 0x8000)); |
1472 | 1501 | u = thresh_val & 0xffff; |
1473 | 1502 | if (u < 0x8000) |
1474 | | pout(" Peak value detector threshold (us): %u\n", |
| 1503 | jout(" Peak value detector threshold (us): %u\n", |
1475 | 1504 | u); |
1476 | 1505 | else |
1477 | | pout(" Peak value detector threshold (ms): %u\n", |
| 1506 | jout(" Peak value detector threshold (ms): %u\n", |
1478 | 1507 | 33 + (u - 0x8000)); |
1479 | 1508 | break; |
1480 | 1509 | case 0x2d: |
1481 | | pout(" Peak arbitration time (us): %u\n", val); |
1482 | | pout(" Peak value detector threshold: %u\n", thresh_val); |
| 1510 | jout(" Peak arbitration time (us): %u\n", val); |
| 1511 | jout(" Peak value detector threshold: %u\n", thresh_val); |
1483 | 1512 | break; |
1484 | 1513 | case 0x2e: |
1485 | | pout(" Peak connection time (us): %u\n", val); |
1486 | | pout(" Peak value detector threshold: %u\n", thresh_val); |
| 1514 | jout(" Peak connection time (us): %u\n", val); |
| 1515 | jout(" Peak value detector threshold: %u\n", thresh_val); |
1487 | 1516 | break; |
1488 | 1517 | case 0x40: |
1489 | | pout(" Transmitted SSP frame count: %u\n", val); |
| 1518 | jout(" Transmitted SSP frame count: %u\n", val); |
1490 | 1519 | break; |
1491 | 1520 | case 0x41: |
1492 | | pout(" Received SSP frame count: %u\n", val); |
| 1521 | jout(" Received SSP frame count: %u\n", val); |
1493 | 1522 | break; |
1494 | 1523 | case 0x42: |
1495 | | pout(" Transmitted SSP frame error count: %u\n", val); |
| 1524 | jout(" Transmitted SSP frame error count: %u\n", val); |
1496 | 1525 | break; |
1497 | 1526 | case 0x43: |
1498 | | pout(" Received SSP frame error count: %u\n", val); |
| 1527 | jout(" Received SSP frame error count: %u\n", val); |
1499 | 1528 | break; |
1500 | 1529 | case 0x44: |
1501 | | pout(" Transmitted CREDIT_BLOCKED count: %u\n", val); |
| 1530 | jout(" Transmitted CREDIT_BLOCKED count: %u\n", val); |
1502 | 1531 | break; |
1503 | 1532 | case 0x45: |
1504 | | pout(" Received CREDIT_BLOCKED count: %u\n", val); |
| 1533 | jout(" Received CREDIT_BLOCKED count: %u\n", val); |
1505 | 1534 | break; |
1506 | 1535 | case 0x50: |
1507 | | pout(" Transmitted SATA frame count: %u\n", val); |
| 1536 | jout(" Transmitted SATA frame count: %u\n", val); |
1508 | 1537 | break; |
1509 | 1538 | case 0x51: |
1510 | | pout(" Received SATA frame count: %u\n", val); |
| 1539 | jout(" Received SATA frame count: %u\n", val); |
1511 | 1540 | break; |
1512 | 1541 | case 0x52: |
1513 | | pout(" SATA flow control buffer overflow count: %u\n", val); |
| 1542 | jout(" SATA flow control buffer overflow count: %u\n", val); |
1514 | 1543 | break; |
1515 | 1544 | case 0x60: |
1516 | | pout(" Transmitted SMP frame count: %u\n", val); |
| 1545 | jout(" Transmitted SMP frame count: %u\n", val); |
1517 | 1546 | break; |
1518 | 1547 | case 0x61: |
1519 | | pout(" Received SMP frame count: %u\n", val); |
| 1548 | jout(" Received SMP frame count: %u\n", val); |
1520 | 1549 | break; |
1521 | 1550 | case 0x63: |
1522 | | pout(" Received SMP frame error count: %u\n", val); |
| 1551 | jout(" Received SMP frame error count: %u\n", val); |
1523 | 1552 | break; |
1524 | 1553 | default: |
1525 | 1554 | break; |
… |
… |
show_sas_port_param(unsigned char * ucp, int param_len)
|
1536 | 1565 | sz = sizeof(s); |
1537 | 1566 | // pcb = ucp[2]; |
1538 | 1567 | t = sg_get_unaligned_be16(ucp + 0); |
1539 | | pout("relative target port id = %d\n", t); |
1540 | | pout(" generation code = %d\n", ucp[6]); |
| 1568 | jout("relative target port id = %d\n", t); |
| 1569 | jout(" generation code = %d\n", ucp[6]); |
1541 | 1570 | nphys = ucp[7]; |
1542 | | pout(" number of phys = %d\n", nphys); |
| 1571 | jout(" number of phys = %d\n", nphys); |
1543 | 1572 | |
1544 | 1573 | for (j = 0, vcp = ucp + 8; j < (param_len - 8); |
1545 | 1574 | vcp += spld_len, j += spld_len) { |
1546 | | pout(" phy identifier = %d\n", vcp[1]); |
| 1575 | jout(" phy identifier = %d\n", vcp[1]); |
1547 | 1576 | spld_len = vcp[3]; |
1548 | 1577 | if (spld_len < 44) |
1549 | 1578 | spld_len = 48; /* in SAS-1 and SAS-1.1 vcp[3]==0 */ |
… |
… |
show_sas_port_param(unsigned char * ucp, int param_len)
|
1557 | 1586 | case 3: snprintf(s, sz, "expander device (fanout)"); break; |
1558 | 1587 | default: snprintf(s, sz, "reserved [%d]", t); break; |
1559 | 1588 | } |
1560 | | pout(" attached device type: %s\n", s); |
| 1589 | jout(" attached device type: %s\n", s); |
1561 | 1590 | t = 0xf & vcp[4]; |
1562 | 1591 | switch (t) { |
1563 | 1592 | case 0: snprintf(s, sz, "unknown"); break; |
… |
… |
show_sas_port_param(unsigned char * ucp, int param_len)
|
1574 | 1603 | break; |
1575 | 1604 | default: snprintf(s, sz, "reserved [0x%x]", t); break; |
1576 | 1605 | } |
1577 | | pout(" attached reason: %s\n", s); |
| 1606 | jout(" attached reason: %s\n", s); |
1578 | 1607 | t = (vcp[5] & 0xf0) >> 4; |
1579 | 1608 | switch (t) { |
1580 | 1609 | case 0: snprintf(s, sz, "unknown"); break; |
… |
… |
show_sas_port_param(unsigned char * ucp, int param_len)
|
1591 | 1620 | break; |
1592 | 1621 | default: snprintf(s, sz, "reserved [0x%x]", t); break; |
1593 | 1622 | } |
1594 | | pout(" reason: %s\n", s); |
| 1623 | jout(" reason: %s\n", s); |
1595 | 1624 | t = (0xf & vcp[5]); |
1596 | 1625 | switch (t) { |
1597 | 1626 | case 0: snprintf(s, sz, "phy enabled; unknown"); |
… |
… |
show_sas_port_param(unsigned char * ucp, int param_len)
|
1613 | 1642 | case 0xb: snprintf(s, sz, "phy enabled; 12 Gbps"); break; |
1614 | 1643 | default: snprintf(s, sz, "reserved [%d]", t); break; |
1615 | 1644 | } |
1616 | | pout(" negotiated logical link rate: %s\n", s); |
1617 | | pout(" attached initiator port: ssp=%d stp=%d smp=%d\n", |
| 1645 | jout(" negotiated logical link rate: %s\n", s); |
| 1646 | jout(" attached initiator port: ssp=%d stp=%d smp=%d\n", |
1618 | 1647 | !! (vcp[6] & 8), !! (vcp[6] & 4), !! (vcp[6] & 2)); |
1619 | | pout(" attached target port: ssp=%d stp=%d smp=%d\n", |
| 1648 | jout(" attached target port: ssp=%d stp=%d smp=%d\n", |
1620 | 1649 | !! (vcp[7] & 8), !! (vcp[7] & 4), !! (vcp[7] & 2)); |
1621 | 1650 | if (!dont_print_serial_number) { |
1622 | 1651 | uint64_t ull = sg_get_unaligned_be64(vcp + 8); |
1623 | 1652 | |
1624 | | pout(" SAS address = 0x%" PRIx64 "\n", ull); |
| 1653 | jout(" SAS address = 0x%" PRIx64 "\n", ull); |
1625 | 1654 | ull = sg_get_unaligned_be64(vcp + 16); |
1626 | | pout(" attached SAS address = 0x%" PRIx64 "\n", ull); |
| 1655 | jout(" attached SAS address = 0x%" PRIx64 "\n", ull); |
1627 | 1656 | } |
1628 | | pout(" attached phy identifier = %d\n", vcp[24]); |
| 1657 | jout(" attached phy identifier = %d\n", vcp[24]); |
1629 | 1658 | unsigned int ui = sg_get_unaligned_be32(vcp + 32); |
1630 | 1659 | |
1631 | | pout(" Invalid DWORD count = %u\n", ui); |
| 1660 | jout(" Invalid DWORD count = %u\n", ui); |
1632 | 1661 | ui = sg_get_unaligned_be32(vcp + 36); |
1633 | | pout(" Running disparity error count = %u\n", ui); |
| 1662 | jout(" Running disparity error count = %u\n", ui); |
1634 | 1663 | ui = sg_get_unaligned_be32(vcp + 40); |
1635 | | pout(" Loss of DWORD synchronization = %u\n", ui); |
| 1664 | jout(" Loss of DWORD synchronization = %u\n", ui); |
1636 | 1665 | ui = sg_get_unaligned_be32(vcp + 44); |
1637 | | pout(" Phy reset problem = %u\n", ui); |
| 1666 | jout(" Phy reset problem = %u\n", ui); |
1638 | 1667 | if (spld_len > 51) { |
1639 | 1668 | int num_ped; |
1640 | 1669 | unsigned char * xcp; |
1641 | 1670 | |
1642 | 1671 | num_ped = vcp[51]; |
1643 | 1672 | if (num_ped > 0) |
1644 | | pout(" Phy event descriptors:\n"); |
| 1673 | jout(" Phy event descriptors:\n"); |
1645 | 1674 | xcp = vcp + 52; |
1646 | 1675 | for (m = 0; m < (num_ped * 12); m += 12, xcp += 12) { |
1647 | 1676 | int peis; |
… |
… |
show_protocol_specific_page(unsigned char * resp, int len)
|
1668 | 1697 | if (SCSI_TPROTO_SAS != (0xf & ucp[4])) |
1669 | 1698 | return 0; /* only decode SAS log page */ |
1670 | 1699 | if (0 == k) |
1671 | | pout("Protocol Specific port log page for SAS SSP\n"); |
| 1700 | jout("Protocol Specific port log page for SAS SSP\n"); |
1672 | 1701 | show_sas_port_param(ucp, param_len); |
1673 | 1702 | k += param_len; |
1674 | 1703 | ucp += param_len; |
1675 | 1704 | } |
1676 | | pout("\n"); |
| 1705 | jout("\n"); |
1677 | 1706 | return 1; |
1678 | 1707 | } |
1679 | 1708 | |
… |
… |
scsiPrintSasPhy(scsi_device * device, int reset)
|
1689 | 1718 | if ((err = scsiLogSense(device, PROTOCOL_SPECIFIC_LPAGE, 0, gBuf, |
1690 | 1719 | LOG_RESP_LONG_LEN, 0))) { |
1691 | 1720 | print_on(); |
1692 | | pout("%s %s Failed [%s]\n\n", __func__, logSenStr, |
| 1721 | jout("%s %s Failed [%s]\n\n", __func__, logSenStr, |
1693 | 1722 | scsiErrString(err)); |
1694 | 1723 | print_off(); |
1695 | 1724 | return FAILSMART; |
1696 | 1725 | } |
1697 | 1726 | if ((gBuf[0] & 0x3f) != PROTOCOL_SPECIFIC_LPAGE) { |
1698 | 1727 | print_on(); |
1699 | | pout("%s %s, page mismatch\n\n", hname, logSenRspStr); |
| 1728 | jout("%s %s, page mismatch\n\n", hname, logSenRspStr); |
1700 | 1729 | print_off(); |
1701 | 1730 | return FAILSMART; |
1702 | 1731 | } |
… |
… |
scsiPrintSasPhy(scsi_device * device, int reset)
|
1704 | 1733 | num = sg_get_unaligned_be16(gBuf + 2); |
1705 | 1734 | if (1 != show_protocol_specific_page(gBuf, num + 4)) { |
1706 | 1735 | print_on(); |
1707 | | pout("Only support %s log page on SAS devices\n\n", hname); |
| 1736 | jout("Only support %s log page on SAS devices\n\n", hname); |
1708 | 1737 | print_off(); |
1709 | 1738 | return FAILSMART; |
1710 | 1739 | } |
… |
… |
scsiPrintSasPhy(scsi_device * device, int reset)
|
1712 | 1741 | if ((err = scsiLogSelect(device, 1 /* pcr */, 0 /* sp */, 0 /* pc */, |
1713 | 1742 | PROTOCOL_SPECIFIC_LPAGE, 0, NULL, 0))) { |
1714 | 1743 | print_on(); |
1715 | | pout("%s Log Select (reset) Failed [%s]\n\n", __func__, |
| 1744 | jout("%s Log Select (reset) Failed [%s]\n\n", __func__, |
1716 | 1745 | scsiErrString(err)); |
1717 | 1746 | print_off(); |
1718 | 1747 | return FAILSMART; |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
1794 | 1823 | req_len = 36; |
1795 | 1824 | if ((err = scsiStdInquiry(device, gBuf, req_len))) { |
1796 | 1825 | print_on(); |
1797 | | pout("Standard Inquiry (36 bytes) failed [%s]\n", scsiErrString(err)); |
1798 | | pout("Retrying with a 64 byte Standard Inquiry\n"); |
| 1826 | jout("Standard Inquiry (36 bytes) failed [%s]\n", scsiErrString(err)); |
| 1827 | jout("Retrying with a 64 byte Standard Inquiry\n"); |
1799 | 1828 | print_off(); |
1800 | 1829 | /* Marvell controllers fail with 36 byte StdInquiry, but 64 is ok */ |
1801 | 1830 | req_len = 64; |
1802 | 1831 | if ((err = scsiStdInquiry(device, gBuf, req_len))) { |
1803 | 1832 | print_on(); |
1804 | | pout("Standard Inquiry (64 bytes) failed [%s]\n", |
| 1833 | jout("Standard Inquiry (64 bytes) failed [%s]\n", |
1805 | 1834 | scsiErrString(err)); |
1806 | 1835 | print_off(); |
1807 | 1836 | return 1; |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
1817 | 1846 | |
1818 | 1847 | if (len < 36) { |
1819 | 1848 | print_on(); |
1820 | | pout("Short INQUIRY response, skip product id\n"); |
| 1849 | jout("Short INQUIRY response, skip product id\n"); |
1821 | 1850 | print_off(); |
1822 | 1851 | return 1; |
1823 | 1852 | } |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
1831 | 1860 | scsi_format_id_string(product, &gBuf[16], 16); |
1832 | 1861 | scsi_format_id_string(revision, &gBuf[32], 4); |
1833 | 1862 | |
1834 | | pout("=== START OF INFORMATION SECTION ===\n"); |
| 1863 | jout("=== START OF INFORMATION SECTION ===\n"); |
1835 | 1864 | jout("Vendor: %.8s\n", scsi_vendor); |
1836 | 1865 | jglb["vendor"] = scsi_vendor; |
1837 | 1866 | jout("Product: %.16s\n", product); |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
1854 | 1883 | |
1855 | 1884 | if (!*device->get_req_type()/*no type requested*/ && |
1856 | 1885 | (0 == strncmp((char *)&gBuf[8], "ATA", 3))) { |
1857 | | pout("\nProbable ATA device behind a SAT layer\n" |
| 1886 | jout("\nProbable ATA device behind a SAT layer\n" |
1858 | 1887 | "Try an additional '-d ata' or '-d sat' argument.\n"); |
1859 | 1888 | return 2; |
1860 | 1889 | } |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
1888 | 1917 | jout("Physical block size: %u bytes\n", pb_size); |
1889 | 1918 | jglb["physical_block_size"] = pb_size; |
1890 | 1919 | if (srr.l_a_lba > 0) // not common so cut the clutter |
1891 | | pout("Lowest aligned LBA: %u\n", srr.l_a_lba); |
| 1920 | jout("Lowest aligned LBA: %u\n", srr.l_a_lba); |
1892 | 1921 | } |
1893 | 1922 | if (srr.prot_type > 0) { |
1894 | 1923 | switch (srr.prot_type) { |
1895 | 1924 | case 1 : |
1896 | | pout("Formatted with type 1 protection\n"); |
| 1925 | jout("Formatted with type 1 protection\n"); |
1897 | 1926 | break; |
1898 | 1927 | case 2 : |
1899 | | pout("Formatted with type 2 protection\n"); |
| 1928 | jout("Formatted with type 2 protection\n"); |
1900 | 1929 | break; |
1901 | 1930 | case 3 : |
1902 | | pout("Formatted with type 3 protection\n"); |
| 1931 | jout("Formatted with type 3 protection\n"); |
1903 | 1932 | break; |
1904 | 1933 | default: |
1905 | | pout("Formatted with unknown protection type [%d]\n", |
| 1934 | jout("Formatted with unknown protection type [%d]\n", |
1906 | 1935 | srr.prot_type); |
1907 | 1936 | break; |
1908 | 1937 | } |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
1911 | 1940 | app-tag(2), tag-mask(2) */ |
1912 | 1941 | |
1913 | 1942 | if (p_i_per_lb > 1) |
1914 | | pout("%d protection information intervals per " |
| 1943 | jout("%d protection information intervals per " |
1915 | 1944 | "logical block\n", p_i_per_lb); |
1916 | | pout("%d bytes of protection information per logical " |
| 1945 | jout("%d bytes of protection information per logical " |
1917 | 1946 | "block\n", pi_sz * p_i_per_lb); |
1918 | 1947 | } |
1919 | 1948 | /* Pick up some LB provisioning info since its available */ |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
1938 | 1967 | switch (prov_type) { |
1939 | 1968 | case 0: |
1940 | 1969 | if (lbpme <= 0) { |
1941 | | pout("LU is fully provisioned"); |
| 1970 | jout("LU is fully provisioned"); |
1942 | 1971 | if (lbprz) |
1943 | | pout(" [LBPRZ=%d]\n", lbprz); |
| 1972 | jout(" [LBPRZ=%d]\n", lbprz); |
1944 | 1973 | else |
1945 | | pout("\n"); |
| 1974 | jout("\n"); |
1946 | 1975 | } else |
1947 | | pout("LB provisioning type: not reported [LBPME=1, " |
| 1976 | jout("LB provisioning type: not reported [LBPME=1, " |
1948 | 1977 | "LBPRZ=%d]\n", lbprz); |
1949 | 1978 | break; |
1950 | 1979 | case 1: |
1951 | | pout("LU is resource provisioned, LBPRZ=%d\n", lbprz); |
| 1980 | jout("LU is resource provisioned, LBPRZ=%d\n", lbprz); |
1952 | 1981 | break; |
1953 | 1982 | case 2: |
1954 | | pout("LU is thin provisioned, LBPRZ=%d\n", lbprz); |
| 1983 | jout("LU is thin provisioned, LBPRZ=%d\n", lbprz); |
1955 | 1984 | break; |
1956 | 1985 | default: |
1957 | | pout("LU provisioning type reserved [%d], LBPRZ=%d\n", |
| 1986 | jout("LU provisioning type reserved [%d], LBPRZ=%d\n", |
1958 | 1987 | prov_type, lbprz); |
1959 | 1988 | break; |
1960 | 1989 | } |
1961 | 1990 | } else if (1 == lbpme) { |
1962 | 1991 | if (scsi_debugmode > 0) |
1963 | | pout("rcap_16 sets LBPME but no LB provisioning VPD page\n"); |
1964 | | pout("Logical block provisioning enabled, LBPRZ=%d\n", lbprz); |
| 1992 | jout("rcap_16 sets LBPME but no LB provisioning VPD page\n"); |
| 1993 | jout("Logical block provisioning enabled, LBPRZ=%d\n", lbprz); |
1965 | 1994 | } |
1966 | 1995 | |
1967 | 1996 | int rpm = scsiGetRPM(device, modese_len, &form_factor, &haw_zbc); |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
2003 | 2032 | } |
2004 | 2033 | } |
2005 | 2034 | if (haw_zbc > 0) |
2006 | | pout("Host aware zoned block capable\n"); |
| 2035 | jout("Host aware zoned block capable\n"); |
2007 | 2036 | } |
2008 | 2037 | |
2009 | 2038 | /* Do this here to try and detect badly conforming devices (some USB |
2010 | 2039 | keys) that will lock up on a InquiryVpd or log sense or ... */ |
2011 | 2040 | if ((iec_err = scsiFetchIECmpage(device, &iec, modese_len))) { |
2012 | 2041 | if (SIMPLE_ERR_BAD_RESP == iec_err) { |
2013 | | pout(">> Terminate command early due to bad response to IEC " |
| 2042 | jout(">> Terminate command early due to bad response to IEC " |
2014 | 2043 | "mode page\n"); |
2015 | 2044 | print_off(); |
2016 | 2045 | gIecMPage = 0; |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
2027 | 2056 | len = gBuf[3]; |
2028 | 2057 | scsi_decode_lu_dev_id(gBuf + 4, len, s, sizeof(s), &transport); |
2029 | 2058 | if (strlen(s) > 0) |
2030 | | pout("Logical Unit id: %s\n", s); |
| 2059 | jout("Logical Unit id: %s\n", s); |
2031 | 2060 | } else if (scsi_debugmode > 0) { |
2032 | 2061 | print_on(); |
2033 | 2062 | if (SIMPLE_ERR_BAD_RESP == err) |
2034 | | pout("Vital Product Data (VPD) bit ignored in INQUIRY\n"); |
| 2063 | jout("Vital Product Data (VPD) bit ignored in INQUIRY\n"); |
2035 | 2064 | else |
2036 | | pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err); |
| 2065 | jout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err); |
2037 | 2066 | print_off(); |
2038 | 2067 | } |
2039 | 2068 | if (0 == (err = scsiInquiryVpd(device, SCSI_VPD_UNIT_SERIAL_NUMBER, |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
2048 | 2077 | } else if (scsi_debugmode > 0) { |
2049 | 2078 | print_on(); |
2050 | 2079 | if (SIMPLE_ERR_BAD_RESP == err) |
2051 | | pout("Vital Product Data (VPD) bit ignored in INQUIRY\n"); |
| 2080 | jout("Vital Product Data (VPD) bit ignored in INQUIRY\n"); |
2052 | 2081 | else |
2053 | | pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err); |
| 2082 | jout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err); |
2054 | 2083 | print_off(); |
2055 | 2084 | } |
2056 | 2085 | } |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
2069 | 2098 | if (transport < 0) |
2070 | 2099 | transport = scsiFetchTransportProtocol(device, modese_len); |
2071 | 2100 | if ((transport >= 0) && (transport <= 0xf)) |
2072 | | pout("Transport protocol: %s\n", transport_proto_arr[transport]); |
| 2101 | jout("Transport protocol: %s\n", transport_proto_arr[transport]); |
2073 | 2102 | |
2074 | 2103 | // print current time and date and timezone |
2075 | 2104 | time_t now = time(0); |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
2083 | 2112 | if (SIMPLE_ERR_NOT_READY == err) { |
2084 | 2113 | print_on(); |
2085 | 2114 | if (!is_tape) |
2086 | | pout("device is NOT READY (e.g. spun down, busy)\n"); |
| 2115 | jout("device is NOT READY (e.g. spun down, busy)\n"); |
2087 | 2116 | else |
2088 | | pout("device is NOT READY (e.g. no tape)\n"); |
| 2117 | jout("device is NOT READY (e.g. no tape)\n"); |
2089 | 2118 | print_off(); |
2090 | 2119 | } else if (SIMPLE_ERR_NO_MEDIUM == err) { |
2091 | 2120 | print_on(); |
2092 | 2121 | if (is_tape) |
2093 | | pout("NO tape present in drive\n"); |
| 2122 | jout("NO tape present in drive\n"); |
2094 | 2123 | else |
2095 | | pout("NO MEDIUM present in device\n"); |
| 2124 | jout("NO MEDIUM present in device\n"); |
2096 | 2125 | print_off(); |
2097 | 2126 | } else if (SIMPLE_ERR_BECOMING_READY == err) { |
2098 | 2127 | print_on(); |
2099 | | pout("device becoming ready (wait)\n"); |
| 2128 | jout("device becoming ready (wait)\n"); |
2100 | 2129 | print_off(); |
2101 | 2130 | } else { |
2102 | 2131 | print_on(); |
2103 | | pout("device Test Unit Ready [%s]\n", scsiErrString(err)); |
| 2132 | jout("device Test Unit Ready [%s]\n", scsiErrString(err)); |
2104 | 2133 | print_off(); |
2105 | 2134 | } |
2106 | 2135 | if (! is_tape) { |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
2113 | 2142 | if (iec_err) { |
2114 | 2143 | if (!is_tape) { |
2115 | 2144 | print_on(); |
2116 | | pout("SMART support is: Unavailable - device lacks SMART " |
| 2145 | jout("SMART support is: Unavailable - device lacks SMART " |
2117 | 2146 | "capability.\n"); |
2118 | 2147 | if (scsi_debugmode > 0) |
2119 | | pout(" [%s]\n", scsiErrString(iec_err)); |
| 2148 | jout(" [%s]\n", scsiErrString(iec_err)); |
2120 | 2149 | print_off(); |
2121 | 2150 | } |
2122 | 2151 | gIecMPage = 0; |
… |
… |
scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
|
2124 | 2153 | } |
2125 | 2154 | |
2126 | 2155 | if (!is_tape) |
2127 | | pout("SMART support is: Available - device has SMART capability.\n" |
| 2156 | jout("SMART support is: Available - device has SMART capability.\n" |
2128 | 2157 | "SMART support is: %s\n", |
2129 | 2158 | (scsi_IsExceptionControlEnabled(&iec)) ? "Enabled" : "Disabled"); |
2130 | | pout("%s\n", (scsi_IsWarningEnabled(&iec)) ? |
| 2159 | jout("%s\n", (scsi_IsWarningEnabled(&iec)) ? |
2131 | 2160 | "Temperature Warning: Enabled" : |
2132 | 2161 | "Temperature Warning: Disabled or Not Supported"); |
2133 | 2162 | return 0; |
… |
… |
scsiSmartEnable(scsi_device * device)
|
2141 | 2170 | |
2142 | 2171 | if ((err = scsiFetchIECmpage(device, &iec, modese_len))) { |
2143 | 2172 | print_on(); |
2144 | | pout("unable to fetch IEC (SMART) mode page [%s]\n", |
| 2173 | jout("unable to fetch IEC (SMART) mode page [%s]\n", |
2145 | 2174 | scsiErrString(err)); |
2146 | 2175 | print_off(); |
2147 | 2176 | return 1; |
… |
… |
scsiSmartEnable(scsi_device * device)
|
2150 | 2179 | |
2151 | 2180 | if ((err = scsiSetExceptionControlAndWarning(device, 1, &iec))) { |
2152 | 2181 | print_on(); |
2153 | | pout("unable to enable Exception control and warning [%s]\n", |
| 2182 | jout("unable to enable Exception control and warning [%s]\n", |
2154 | 2183 | scsiErrString(err)); |
2155 | 2184 | print_off(); |
2156 | 2185 | return 1; |
2157 | 2186 | } |
2158 | 2187 | /* Need to refetch 'iec' since could be modified by previous call */ |
2159 | 2188 | if ((err = scsiFetchIECmpage(device, &iec, modese_len))) { |
2160 | | pout("unable to fetch IEC (SMART) mode page [%s]\n", |
| 2189 | jout("unable to fetch IEC (SMART) mode page [%s]\n", |
2161 | 2190 | scsiErrString(err)); |
2162 | 2191 | return 1; |
2163 | 2192 | } else |
2164 | 2193 | modese_len = iec.modese_len; |
2165 | 2194 | |
2166 | | pout("Informational Exceptions (SMART) %s\n", |
| 2195 | jout("Informational Exceptions (SMART) %s\n", |
2167 | 2196 | scsi_IsExceptionControlEnabled(&iec) ? "enabled" : "disabled"); |
2168 | | pout("Temperature warning %s\n", |
| 2197 | jout("Temperature warning %s\n", |
2169 | 2198 | scsi_IsWarningEnabled(&iec) ? "enabled" : "disabled"); |
2170 | 2199 | return 0; |
2171 | 2200 | } |
… |
… |
scsiSmartDisable(scsi_device * device)
|
2178 | 2207 | |
2179 | 2208 | if ((err = scsiFetchIECmpage(device, &iec, modese_len))) { |
2180 | 2209 | print_on(); |
2181 | | pout("unable to fetch IEC (SMART) mode page [%s]\n", |
| 2210 | jout("unable to fetch IEC (SMART) mode page [%s]\n", |
2182 | 2211 | scsiErrString(err)); |
2183 | 2212 | print_off(); |
2184 | 2213 | return 1; |
… |
… |
scsiSmartDisable(scsi_device * device)
|
2187 | 2216 | |
2188 | 2217 | if ((err = scsiSetExceptionControlAndWarning(device, 0, &iec))) { |
2189 | 2218 | print_on(); |
2190 | | pout("unable to disable Exception control and warning [%s]\n", |
| 2219 | jout("unable to disable Exception control and warning [%s]\n", |
2191 | 2220 | scsiErrString(err)); |
2192 | 2221 | print_off(); |
2193 | 2222 | return 1; |
2194 | 2223 | } |
2195 | 2224 | /* Need to refetch 'iec' since could be modified by previous call */ |
2196 | 2225 | if ((err = scsiFetchIECmpage(device, &iec, modese_len))) { |
2197 | | pout("unable to fetch IEC (SMART) mode page [%s]\n", |
| 2226 | jout("unable to fetch IEC (SMART) mode page [%s]\n", |
2198 | 2227 | scsiErrString(err)); |
2199 | 2228 | return 1; |
2200 | 2229 | } else |
2201 | 2230 | modese_len = iec.modese_len; |
2202 | 2231 | |
2203 | | pout("Informational Exceptions (SMART) %s\n", |
| 2232 | jout("Informational Exceptions (SMART) %s\n", |
2204 | 2233 | scsi_IsExceptionControlEnabled(&iec) ? "enabled" : "disabled"); |
2205 | | pout("Temperature warning %s\n", |
| 2234 | jout("Temperature warning %s\n", |
2206 | 2235 | scsi_IsWarningEnabled(&iec) ? "enabled" : "disabled"); |
2207 | 2236 | return 0; |
2208 | 2237 | } |
… |
… |
scsiPrintTemp(scsi_device * device)
|
2217 | 2246 | return; |
2218 | 2247 | |
2219 | 2248 | if (255 == temp) |
2220 | | pout("Current Drive Temperature: <not available>\n"); |
| 2249 | jout("Current Drive Temperature: <not available>\n"); |
2221 | 2250 | else { |
2222 | 2251 | jout("Current Drive Temperature: %d C\n", temp); |
2223 | 2252 | jglb["temperature"]["current"] = temp; |
2224 | 2253 | } |
2225 | 2254 | if (255 == trip) |
2226 | | pout("Drive Trip Temperature: <not available>\n"); |
2227 | | else |
2228 | | pout("Drive Trip Temperature: %d C\n", trip); |
2229 | | pout("\n"); |
| 2255 | jout("Drive Trip Temperature: <not available>\n"); |
| 2256 | else { |
| 2257 | jout("Drive Trip Temperature: %d C\n", trip); |
| 2258 | jglb["temperature"]["drive_trip"] = trip; |
| 2259 | } |
| 2260 | jout("\n"); |
2230 | 2261 | } |
2231 | 2262 | |
2232 | 2263 | /* Main entry point used by smartctl command. Return 0 for success */ |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2268 | 2299 | if (is_disk) { |
2269 | 2300 | res = scsiGetSetCache(device, modese_len, &wce, &rcd); |
2270 | 2301 | if (options.get_rcd) |
2271 | | pout("Read Cache is: %s\n", |
| 2302 | jout("Read Cache is: %s\n", |
2272 | 2303 | res ? "Unavailable" : // error |
2273 | 2304 | rcd ? "Disabled" : "Enabled"); |
2274 | 2305 | if (options.get_wce) |
2275 | | pout("Writeback Cache is: %s\n", |
| 2306 | jout("Writeback Cache is: %s\n", |
2276 | 2307 | res ? "Unavailable" : // error |
2277 | 2308 | !wce ? "Disabled" : "Enabled"); |
2278 | 2309 | } |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2280 | 2311 | any_output = true; |
2281 | 2312 | |
2282 | 2313 | if (options.drive_info) |
2283 | | pout("\n"); |
| 2314 | jout("\n"); |
2284 | 2315 | |
2285 | 2316 | // START OF THE ENABLE/DISABLE SECTION OF THE CODE |
2286 | 2317 | if (options.smart_disable || options.smart_enable || |
2287 | 2318 | options.smart_auto_save_disable || options.smart_auto_save_enable) |
2288 | | pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n"); |
| 2319 | jout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n"); |
2289 | 2320 | |
2290 | 2321 | if (options.smart_enable) { |
2291 | 2322 | if (scsiSmartEnable(device)) |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2301 | 2332 | |
2302 | 2333 | if (options.smart_auto_save_enable) { |
2303 | 2334 | if (scsiSetControlGLTSD(device, 0, modese_len)) { |
2304 | | pout("Enable autosave (clear GLTSD bit) failed\n"); |
| 2335 | jout("Enable autosave (clear GLTSD bit) failed\n"); |
2305 | 2336 | failuretest(OPTIONAL_CMD,returnval |= FAILSMART); |
2306 | 2337 | } else |
2307 | | pout("Autosave enabled (GLTSD bit cleared).\n"); |
| 2338 | jout("Autosave enabled (GLTSD bit cleared).\n"); |
2308 | 2339 | any_output = true; |
2309 | 2340 | } |
2310 | 2341 | |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2314 | 2345 | |
2315 | 2346 | rcd = -1; |
2316 | 2347 | if (scsiGetSetCache(device, modese_len, &wce, &rcd)) { |
2317 | | pout("Write cache %sable failed: %s\n", (enable ? "en" : "dis"), |
| 2348 | jout("Write cache %sable failed: %s\n", (enable ? "en" : "dis"), |
2318 | 2349 | device->get_errmsg()); |
2319 | 2350 | failuretest(OPTIONAL_CMD,returnval |= FAILSMART); |
2320 | 2351 | } else |
2321 | | pout("Write cache %sabled\n", (enable ? "en" : "dis")); |
| 2352 | jout("Write cache %sabled\n", (enable ? "en" : "dis")); |
2322 | 2353 | any_output = true; |
2323 | 2354 | } |
2324 | 2355 | |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2329 | 2360 | rcd = !enable; |
2330 | 2361 | wce = -1; |
2331 | 2362 | if (scsiGetSetCache(device, modese_len, &wce, &rcd)) { |
2332 | | pout("Read cache %sable failed: %s\n", (enable ? "en" : "dis"), |
| 2363 | jout("Read cache %sable failed: %s\n", (enable ? "en" : "dis"), |
2333 | 2364 | device->get_errmsg()); |
2334 | 2365 | failuretest(OPTIONAL_CMD,returnval |= FAILSMART); |
2335 | 2366 | } else |
2336 | | pout("Read cache %sabled\n", (enable ? "en" : "dis")); |
| 2367 | jout("Read cache %sabled\n", (enable ? "en" : "dis")); |
2337 | 2368 | any_output = true; |
2338 | 2369 | } |
2339 | 2370 | |
2340 | 2371 | if (options.smart_auto_save_disable) { |
2341 | 2372 | if (scsiSetControlGLTSD(device, 1, modese_len)) { |
2342 | | pout("Disable autosave (set GLTSD bit) failed\n"); |
| 2373 | jout("Disable autosave (set GLTSD bit) failed\n"); |
2343 | 2374 | failuretest(OPTIONAL_CMD,returnval |= FAILSMART); |
2344 | 2375 | } else |
2345 | | pout("Autosave disabled (GLTSD bit set).\n"); |
| 2376 | jout("Autosave disabled (GLTSD bit set).\n"); |
2346 | 2377 | any_output = true; |
2347 | 2378 | } |
2348 | 2379 | if (options.smart_disable || options.smart_enable || |
2349 | 2380 | options.smart_auto_save_disable || options.smart_auto_save_enable) |
2350 | | pout("\n"); // END OF THE ENABLE/DISABLE SECTION OF THE CODE |
| 2381 | jout("\n"); // END OF THE ENABLE/DISABLE SECTION OF THE CODE |
2351 | 2382 | |
2352 | 2383 | // START OF READ-ONLY OPTIONS APART FROM -V and -i |
2353 | 2384 | if (options.smart_check_status || options.smart_ss_media_log || |
2354 | 2385 | options.smart_vendor_attrib || options.smart_error_log || |
2355 | 2386 | options.smart_selftest_log || options.smart_background_log || |
2356 | 2387 | options.sasphy) |
2357 | | pout("=== START OF READ SMART DATA SECTION ===\n"); |
| 2388 | jout("=== START OF READ SMART DATA SECTION ===\n"); |
2358 | 2389 | |
2359 | 2390 | if (options.smart_check_status) { |
2360 | 2391 | scsiGetSupportedLogPages(device); |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2362 | 2393 | if (is_tape) { |
2363 | 2394 | if (gTapeAlertsLPage) { |
2364 | 2395 | if (options.drive_info) |
2365 | | pout("TapeAlert Supported\n"); |
| 2396 | jout("TapeAlert Supported\n"); |
2366 | 2397 | if (-1 == scsiGetTapeAlertsData(device, peripheral_type)) |
2367 | 2398 | failuretest(OPTIONAL_CMD, returnval |= FAILSMART); |
2368 | 2399 | } |
2369 | 2400 | else |
2370 | | pout("TapeAlert Not Supported\n"); |
| 2401 | jout("TapeAlert Not Supported\n"); |
2371 | 2402 | } else { /* disk, cd/dvd, enclosure, etc */ |
2372 | 2403 | if ((res = scsiGetSmartData(device, |
2373 | 2404 | options.smart_vendor_attrib))) { |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2417 | 2448 | if (gPendDefectsLPage) |
2418 | 2449 | scsiPrintPendingDefectsLPage(device); |
2419 | 2450 | if (1 == scsiFetchControlGLTSD(device, modese_len, 1)) |
2420 | | pout("\n[GLTSD (Global Logging Target Save Disable) set. " |
| 2451 | jout("\n[GLTSD (Global Logging Target Save Disable) set. " |
2421 | 2452 | "Enable Save with '-S on']\n"); |
2422 | 2453 | any_output = true; |
2423 | 2454 | } |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2428 | 2459 | if (gSelfTestLPage) |
2429 | 2460 | res = scsiPrintSelfTest(device); |
2430 | 2461 | else { |
2431 | | pout("Device does not support Self Test logging\n"); |
| 2462 | jout("Device does not support Self Test logging\n"); |
2432 | 2463 | failuretest(OPTIONAL_CMD, returnval|=FAILSMART); |
2433 | 2464 | } |
2434 | 2465 | if (0 != res) |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2442 | 2473 | if (gBackgroundResultsLPage) |
2443 | 2474 | res = scsiPrintBackgroundResults(device); |
2444 | 2475 | else { |
2445 | | pout("Device does not support Background scan results logging\n"); |
| 2476 | jout("Device does not support Background scan results logging\n"); |
2446 | 2477 | failuretest(OPTIONAL_CMD, returnval|=FAILSMART); |
2447 | 2478 | } |
2448 | 2479 | if (0 != res) |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2452 | 2483 | if (options.smart_default_selftest) { |
2453 | 2484 | if (scsiSmartDefaultSelfTest(device)) |
2454 | 2485 | return returnval | FAILSMART; |
2455 | | pout("Default Self Test Successful\n"); |
| 2486 | jout("Default Self Test Successful\n"); |
2456 | 2487 | any_output = true; |
2457 | 2488 | } |
2458 | 2489 | if (options.smart_short_cap_selftest) { |
2459 | 2490 | if (scsiSmartShortCapSelfTest(device)) |
2460 | 2491 | return returnval | FAILSMART; |
2461 | | pout("Short Foreground Self Test Successful\n"); |
| 2492 | jout("Short Foreground Self Test Successful\n"); |
2462 | 2493 | any_output = true; |
2463 | 2494 | } |
2464 | 2495 | // check if another test is running |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2466 | 2497 | if (!scsiRequestSense(device, &sense_info) && |
2467 | 2498 | (sense_info.asc == 0x04 && sense_info.ascq == 0x09)) { |
2468 | 2499 | if (!options.smart_selftest_force) { |
2469 | | pout("Can't start self-test without aborting current test"); |
| 2500 | jout("Can't start self-test without aborting current test"); |
2470 | 2501 | if (sense_info.progress != -1) |
2471 | | pout(" (%d%% remaining)", |
| 2502 | jout(" (%d%% remaining)", |
2472 | 2503 | 100 - sense_info.progress * 100 / 65535); |
2473 | | pout(",\nadd '-t force' option to override, or run " |
| 2504 | jout(",\nadd '-t force' option to override, or run " |
2474 | 2505 | "'smartctl -X' to abort test.\n"); |
2475 | 2506 | return -1; |
2476 | 2507 | } else |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2480 | 2511 | if (options.smart_short_selftest) { |
2481 | 2512 | if (scsiSmartShortSelfTest(device)) |
2482 | 2513 | return returnval | FAILSMART; |
2483 | | pout("Short Background Self Test has begun\n"); |
2484 | | pout("Use smartctl -X to abort test\n"); |
| 2514 | jout("Short Background Self Test has begun\n"); |
| 2515 | jout("Use smartctl -X to abort test\n"); |
2485 | 2516 | any_output = true; |
2486 | 2517 | } |
2487 | 2518 | if (options.smart_extend_selftest) { |
2488 | 2519 | if (scsiSmartExtendSelfTest(device)) |
2489 | 2520 | return returnval | FAILSMART; |
2490 | | pout("Extended Background Self Test has begun\n"); |
| 2521 | jout("Extended Background Self Test has begun\n"); |
2491 | 2522 | if ((0 == scsiFetchExtendedSelfTestTime(device, &durationSec, |
2492 | 2523 | modese_len)) && (durationSec > 0)) { |
2493 | 2524 | time_t t = time(NULL); |
2494 | 2525 | |
2495 | 2526 | t += durationSec; |
2496 | | pout("Please wait %d minutes for test to complete.\n", |
| 2527 | jout("Please wait %d minutes for test to complete.\n", |
2497 | 2528 | durationSec / 60); |
2498 | | pout("Estimated completion time: %s\n", ctime(&t)); |
| 2529 | jout("Estimated completion time: %s\n", ctime(&t)); |
2499 | 2530 | } |
2500 | | pout("Use smartctl -X to abort test\n"); |
| 2531 | jout("Use smartctl -X to abort test\n"); |
2501 | 2532 | any_output = true; |
2502 | 2533 | } |
2503 | 2534 | if (options.smart_extend_cap_selftest) { |
2504 | 2535 | if (scsiSmartExtendCapSelfTest(device)) |
2505 | 2536 | return returnval | FAILSMART; |
2506 | | pout("Extended Foreground Self Test Successful\n"); |
| 2537 | jout("Extended Foreground Self Test Successful\n"); |
2507 | 2538 | } |
2508 | 2539 | if (options.smart_selftest_abort) { |
2509 | 2540 | if (scsiSmartSelfTestAbort(device)) |
2510 | 2541 | return returnval | FAILSMART; |
2511 | | pout("Self Test returned without error\n"); |
| 2542 | jout("Self Test returned without error\n"); |
2512 | 2543 | any_output = true; |
2513 | 2544 | } |
2514 | 2545 | if (options.sasphy && gProtocolSpecificLPage) { |
… |
… |
scsiPrintMain(scsi_device * device, const scsi_print_options & options)
|
2518 | 2549 | } |
2519 | 2550 | |
2520 | 2551 | if (!any_output) |
2521 | | pout("SCSI device successfully opened\n\nUse 'smartctl -a' (or '-x') " |
| 2552 | jout("SCSI device successfully opened\n\nUse 'smartctl -a' (or '-x') " |
2522 | 2553 | "to print SMART (and more) information\n\n"); |
2523 | 2554 | |
2524 | 2555 | return returnval; |