49#define RSOC_RESP_SZ 4096
50#define RSOC_ALL_BYTES_CTDP_0 8
51#define RSOC_ALL_BYTES_CTDP_1 20
57 int k, err, cd_len, bump;
59 uint8_t * rp = (uint8_t *)calloc(
sizeof(uint8_t),
RSOC_RESP_SZ);
60 const uint8_t * last_rp;
77 pout(
"%s response too short\n", __func__);
83 if (cd_len > max_bytes_of_cmds) {
85 pout(
"%s: truncate %d byte response to %d bytes\n", __func__,
86 cd_len, max_bytes_of_cmds);
87 cd_len = max_bytes_of_cmds;
89 last_rp = rp + cd_len;
94 for (k = 0, cmdp = rp + 4; cmdp < last_rp; ++k, cmdp += bump) {
95 bool sa_valid = !! (0x1 & cmdp[5]);
96 bool ctdp = !! (0x2 & cmdp[5]);
119 pout(
"%s: decoded %d supported commands\n", __func__, k);
156 unsigned char b[0xfc] = {};
161 int n =
sizeof(
pages);
174 if (vpd_page_num ==
pages[k])
185 return ((ch >=
' ') && (ch < 0x7f));
193 while ((n > 0) && (
' ' ==
b[n - 1]))
202 void (*out)(
const char *
s,
void * ctx),
void * ctx =
nullptr)
204 static const int line_len = 80;
205 static const int cpstart = 60;
207 char buff[line_len + 2];
213 char e[line_len + 2];
214 static const int elen =
sizeof(e);
218 blen = (int)
sizeof(buff);
219 memset(buff,
' ', line_len);
220 buff[line_len] =
'\0';
224 for (k = 0; k < len; k++) {
226 if (bpos == (bpstart + (8 * 3)))
228 snprintf(&buff[bpos], blen - bpos,
"%.2x", (
int)(uint8_t)c);
229 buff[bpos + 2] =
' ';
230 if ((k > 0) && (0 == ((k + 1) % 16))) {
233 snprintf(e, elen,
"%s\n", buff);
235 snprintf(e, elen,
"%.76s\n", buff);
238 memset(buff,
' ', line_len);
242 if (bpos > bpstart) {
243 buff[bpos + 2] =
'\0';
245 snprintf(e, elen,
"%s\n", buff);
251 k = snprintf(buff + 1, blen - 1,
"%.2x", a);
254 for (i = 0; i < len; i++) {
257 if (bpos == (bpstart + (9 * 3)))
259 snprintf(&buff[bpos], blen - bpos,
"%.2x", (
int)(uint8_t)c);
260 buff[bpos + 2] =
' ';
268 if (cpos > (cpstart + 15)) {
272 snprintf(e, elen,
"%s\n", buff);
274 snprintf(e, elen,
"%.76s\n", buff);
279 memset(buff,
' ', line_len);
280 k = snprintf(buff + 1, blen - 1,
"%.2x", a);
284 if (cpos > cpstart) {
288 snprintf(e, elen,
"%s\n", buff);
297dStrHexFp(
const uint8_t * up,
int len,
int no_ascii, FILE * fp)
302 [](
const char *
s,
void * ctx)
303 { fputs(
s,
reinterpret_cast<FILE *
>(ctx)); },
307 [](
const char *
s,
void *){
pout(
"%s",
s); });
319dStrHex(
const uint8_t * up,
int len,
int no_ascii)
323 [](
const char *
s,
void *){
pout(
"%s",
s); });
347 uint8_t top3bits =
opcode >> 5;
348 if (0x3 == top3bits) {
350 if ((clen < 12) || (clen % 4))
355 return (ilen == clen);
360 return ((ilen == clen) && sa);
364 }
else if (clen <= 16) {
369 return (0x0 == top3bits);
373 return ((0x1 == top3bits) || (0x2 == top3bits));
377 return (0x4 == top3bits);
381 return (0x5 == top3bits);
433 {
INQUIRY,
false, 0,
"inquiry"},
449 "get physical element status"},
453 "report supported operation codes"},
470 static const int sa_var_len =
sizeof(
sa_var_a) /
477 for (k = 0; k < sa_var_len; ++k) {
498 for (k = 0; k < len; ++k) {
509 }
else if (opcode < onp->
opcode)
521 int resp_code = (io_buf->
sensep[0] & 0x7f);
523 if (resp_code >= 0x72) {
527 }
else if (resp_code >= 0x70) {
549 if (0x1 == sinfo->
ascq)
584 return strerror(-scsiErr);
589 return "device not ready";
591 return "unsupported scsi opcode";
593 return "unsupported field in scsi command";
595 return "badly formed scsi parameters";
597 return "scsi response fails sanity test";
599 return "no medium present";
601 return "device will be ready soon";
603 return "unit attention reported, try again";
605 return "medium or hardware error (serious)";
607 return "unknown error (unexpected sense key)";
609 return "aborted command";
611 return "data protection error";
615 return "unknown error";
634 "Vendor specific(9)",
652 if ((sense_key >= 0) && (sense_key < 16))
655 snprintf(buff, buff_len,
"invalid value: 0x%x", sense_key);
670 int * off,
int m_assoc,
int m_desig_type,
int m_code_set)
672 const unsigned char * ucp;
675 for (k = *off, ucp = initial_desig_desc ; (k + 3) < page_len; ) {
676 k = (k < 0) ? 0 : (k + ucp[k + 3] + 4);
677 if ((k + 4) > page_len)
679 int c_set = (ucp[k] & 0xf);
680 if ((m_code_set >= 0) && (m_code_set != c_set))
682 int assoc = ((ucp[k + 1] >> 4) & 0x3);
683 if ((m_assoc >= 0) && (m_assoc != assoc))
685 int desig_type = (ucp[k + 1] & 0xf);
686 if ((m_desig_type >= 0) && (m_desig_type != desig_type))
691 return (k == page_len) ? -1 : -2;
711 int have_scsi_ns = 0;
715 const unsigned char * ucp =
b + off;
717 if ((off + i_len + 4) > blen) {
718 snprintf(
s+si, slen-si,
"error: designator length");
721 int assoc = ((ucp[1] >> 4) & 0x3);
722 if (transport && assoc && (ucp[1] & 0x80) && (*transport < 0))
723 *transport = (ucp[0] >> 4) & 0xf;
726 const unsigned char * ip = ucp + 4;
727 int c_set = (ucp[0] & 0xf);
728 int desig_type = (ucp[1] & 0xf);
731 switch (desig_type) {
736 if ((8 != i_len) && (12 != i_len) && (16 != i_len)) {
737 snprintf(
s+si, slen-si,
"error: EUI-64 length");
742 si += snprintf(
s+si, slen-si,
"0x");
743 for (
int m = 0; m < i_len; ++m)
744 si += snprintf(
s+si, slen-si,
"%02x", (
unsigned int)ip[m]);
748 snprintf(
s+si, slen-si,
"error: NAA bad code_set");
751 naa = (ip[0] >> 4) & 0xff;
752 if ((naa < 2) || (naa > 6) || (4 == naa)) {
753 snprintf(
s+si, slen-si,
"error: unexpected NAA");
760 snprintf(
s+si, slen-si,
"error: NAA 2 length");
763 si += snprintf(
s+si, slen-si,
"0x");
764 for (
int m = 0; m < 8; ++m)
765 si += snprintf(
s+si, slen-si,
"%02x", (
unsigned int)ip[m]);
766 }
else if ((3 == naa ) || (5 == naa)) {
769 snprintf(
s+si, slen-si,
"error: NAA 3 or 5 length");
772 si += snprintf(
s+si, slen-si,
"0x");
773 for (
int m = 0; m < 8; ++m)
774 si += snprintf(
s+si, slen-si,
"%02x", (
unsigned int)ip[m]);
775 }
else if (6 == naa) {
777 snprintf(
s+si, slen-si,
"error: NAA 6 length");
780 si += snprintf(
s+si, slen-si,
"0x");
781 for (
int m = 0; m < 16; ++m)
782 si += snprintf(
s+si, slen-si,
"%02x", (
unsigned int)ip[m]);
792 snprintf(
s+si, slen-si,
"error: SCSI name string");
797 si += snprintf(
s+si, slen-si,
"%s", (
const char *)ip);
806 snprintf(
s+si, slen-si,
"error: bad structure");
825 int bufLen,
int known_resp_len)
830 uint8_t
cdb[10] = {};
833 if (known_resp_len > bufLen)
835 if (known_resp_len > 0)
836 pageLen = known_resp_len;
837 else if (known_resp_len < 0)
842 if (pageLen > bufLen)
845 memset(pBuf, 0, pageLen);
851 cdb[2] = 0x40 | (pagenum & 0x3f);
875 if (pageLen > bufLen)
879 memset(&io_hdr, 0,
sizeof(io_hdr));
880 memset(
cdb, 0,
sizeof(
cdb));
885 cdb[2] = 0x40 | (pagenum & 0x3f);
914 int subpagenum, uint8_t *pBuf,
int bufLen)
918 uint8_t
cdb[10] = {};
925 cdb[1] = (pcr ? 2 : 0) | (sp ? 1 : 0);
926 cdb[2] = ((pc << 6) & 0xc0) | (pagenum & 0x3f);
927 cdb[3] = (subpagenum & 0xff);
946 uint8_t *pBuf,
int bufLen)
953 if ((bufLen < 0) || (bufLen > 255))
959 cdb[2] = (pc << 6) | (pagenum & 0x3f);
977 else if (pagenum != (pBuf[offset] & 0x3f))
997 int pg_offset, pg_len, hdr_plus_1_pg;
999 pg_offset = 4 + pBuf[3];
1000 if (pg_offset + 2 >= bufLen)
1002 pg_len = pBuf[pg_offset + 1] + 2;
1003 hdr_plus_1_pg = pg_offset + pg_len;
1004 if (hdr_plus_1_pg > bufLen)
1007 pBuf[pg_offset] &= 0x7f;
1012 cdb[1] = 0x10 | (sp & 1);
1013 cdb[4] = hdr_plus_1_pg;
1031 uint8_t *pBuf,
int bufLen)
1035 uint8_t
cdb[10] = {};
1042 cdb[2] = (pc << 6) | (pagenum & 0x3f);
1043 cdb[3] = subpagenum;
1060 else if (pagenum != (pBuf[offset] & 0x3f))
1078 uint8_t
cdb[10] = {};
1080 int pg_offset, pg_len, hdr_plus_1_pg;
1083 if (pg_offset + 2 >= bufLen)
1085 pg_len = pBuf[pg_offset + 1] + 2;
1086 hdr_plus_1_pg = pg_offset + pg_len;
1087 if (hdr_plus_1_pg > bufLen)
1091 pBuf[pg_offset] &= 0x7f;
1096 cdb[1] = 0x10 | (sp & 1);
1119 uint8_t
cdb[6] = {};
1122 if ((bufLen < 0) || (bufLen > 1023))
1125 memset(pBuf, 0, 36);
1141 if (((bufLen - io_hdr.
resid) >= 36) &&
1143 ((pBuf[3] & 0xf) == 2)) {
1144 uint8_t pdt = pBuf[0] & 0x1f;
1165 uint8_t
cdb[6] = {};
1175 if ((bufLen < 0) || (bufLen > 1023))
1207 if (vpd_page == pBuf[1]) {
1208 if ((0x80 == vpd_page) && (bufLen > 2) && (0x0 != pBuf[2]))
1222 uint8_t
cdb[6] = {};
1224 uint8_t buff[18] = {};
1226 static const int sz_buff =
sizeof(buff);
1248 uint8_t resp_code = buff[0] & 0x7f;
1251 sense_info->
asc = 0;
1252 sense_info->
ascq = 0;
1253 if ((0x70 == resp_code) || (0x71 == resp_code)) {
1254 int len = buff[7] + 8;
1256 sense_info->
asc = buff[12];
1257 sense_info->
ascq = buff[13];
1262 switch (resp_code) {
1263 const unsigned char * ucp;
1267 sk = (buff[2] & 0xf);
1271 if (buff[15] & 0x80) {
1280 sk = (buff[1] & 0xf);
1283 (0x6 == ucp[1]) && (0x80 & ucp[4])) {
1287 ((0x6 == ucp[1]))) {
1316 uint8_t
cdb[6] = {};
1322 if (power_cond > 0) {
1323 cdb[3] = pcond_modifier & 0xf;
1324 cdb[4] = power_cond << 4;
1348 uint8_t
cdb[6] = {};
1358 cdb[1] = (functioncode & 0x7) << 5;
1380 uint8_t
cdb[6] = {};
1424 int dl_format, uint8_t *pBuf,
int bufLen)
1428 uint8_t
cdb[10] = {};
1435 cdb[2] = (
unsigned char)(((req_plist << 4) & 0x10) |
1436 ((req_glist << 3) & 0x8) | (dl_format & 0x7));
1458 int dl_format,
int addrDescIndex, uint8_t *pBuf,
int bufLen)
1462 uint8_t
cdb[12] = {};
1469 cdb[1] = (
unsigned char)(((req_plist << 4) & 0x10) |
1470 ((req_glist << 3) & 0x8) | (dl_format & 0x7));
1502 const char * ddir =
"none";
1507 ddir = dout ?
"out" :
"in";
1510 pout(
" [%s: ", np ? np :
"<unknown opcode>");
1511 pout(
"SCSI opcode=0x%x, CDB length=%u, data length=0x%u, data "
1523 unsigned int act_len;
1526 (iop->
resid >= 0) && (req_len >= (
unsigned int)iop->
resid)) {
1527 act_len = req_len - (
unsigned int)iop->
resid;
1528 pout(
" [data-in buffer: req_len=%u, resid=%d, gives %u "
1529 "bytes]\n", req_len, iop->
resid, act_len);
1547 pout(
"%s Unit Attention %d: asc/ascq=0x%x,0x%x, retrying\n",
1548 __func__, k + 1, sinfo.
asc, sinfo.
ascq);
1561 unsigned int * lb_sizep)
1566 uint8_t
cdb[10] = {};
1568 uint8_t resp[8] = {};
1600 uint8_t
cdb[16] = {};
1628 uint8_t
cdb[12] = {};
1649 rspLen = bufLen - io_hdr.
resid;
1662 bool try_16 =
false;
1663 bool try_12 =
false;
1664 unsigned int last_lba = 0, lb_size = 0;
1666 uint64_t ret_val = 0;
1667 uint8_t rc16resp[32];
1673 pout(
"%s: READ CAPACITY(10) failed, res=%d\n", __func__, res);
1676 if (0xffffffff == last_lba) {
1681 ret_val = last_lba + 1;
1683 memset(srrp, 0,
sizeof(*srrp));
1690 if (try_16 || (! avoid_rcap16)) {
1694 pout(
"%s: READ CAPACITY(16) failed, res=%d\n", __func__, res);
1704 bool prot_en = !!(0x1 & rc16resp[12]);
1705 uint8_t p_type = ((rc16resp[12] >> 1) & 0x7);
1706 srrp->
prot_type = prot_en ? (1 + p_type) : 0;
1707 srrp->
p_i_exp = ((rc16resp[13] >> 4) & 0xf);
1709 srrp->
lbpme = !!(0x80 & rc16resp[14]);
1710 srrp->
lbprz = !!(0x40 & rc16resp[14]);
1719 pout(
"%s: 2nd READ CAPACITY(10) failed, res=%d\n", __func__,
1723 ret_val = (uint64_t)last_lba + 1;
1725 memset(srrp, 0,
sizeof(*srrp));
1731 return (ret_val * lb_size);
1742 int resp_len, bd_len;
1746 offset = bd_len + 8;
1748 resp_len = resp[0] + 1;
1750 offset = bd_len + 4;
1752 if ((offset + 2) > len) {
1753 pout(
"scsiModePageOffset: raw_curr too small, offset=%d "
1754 "resp_len=%d bd_len=%d\n", offset, resp_len, bd_len);
1756 }
else if ((offset + 2) > resp_len) {
1758 pout(
"scsiModePageOffset: response length too short, "
1759 "resp_len=%d offset=%d bd_len=%d\n", resp_len,
1768#define DEXCPT_ENABLE 0x08
1769#define EWASC_ENABLE 0x10
1770#define DEXCPT_DISABLE 0xf7
1771#define EWASC_DISABLE 0xef
1772#define TEST_DISABLE 0xfb
1785 memset(iecp, 0,
sizeof(*iecp));
1855#define SCSI_IEC_MP_BYTE2_ENABLED 0x10
1856#define SCSI_IEC_MP_BYTE2_TEST_MASK 0x4
1858#define SCSI_IEC_MP_MRIE 6
1859#define SCSI_IEC_MP_INTERVAL_T 0
1860#define SCSI_IEC_MP_REPORT_COUNT 1
1873 int offset, resp_len;
1889 resp_len = rout[0] + 1;
1892 int sp = !! (rout[offset] & 0x80);
1901 uint8_t chg2 = iecp->
raw_chg[offset + 2];
1903 rout[offset + 2] = chg2 ? (rout[offset + 2] & chg2) :
1905 for (
int k = 3; k < 12; ++k) {
1906 if (0 == iecp->
raw_chg[offset + k])
1907 rout[offset + k] = iecp->
raw_curr[offset + k];
1910 if (0 == memcmp(&rout[offset + 2], &iecp->
raw_chg[offset + 2], 10)) {
1912 pout(
"scsiSetExceptionControlAndWarning: already enabled\n");
1917 int wEnabled = (rout[offset + 2] &
EWASC_ENABLE) ? 1 : 0;
1918 if ((! eCEnabled) && (! wEnabled)) {
1920 pout(
"scsiSetExceptionControlAndWarning: already disabled\n");
1942 uint8_t tBuf[252] = {};
1946 sizeof(tBuf), 0))) {
1953 *currenttemp = tBuf[9];
1954 *triptemp = tBuf[15];
1969 uint8_t *
asc, uint8_t *
ascq, uint8_t *currenttemp,
1972 uint8_t tBuf[252] = {};
1975 uint8_t currTemp, trTemp;
1977 memset(&sense_info, 0,
sizeof(sense_info));
1984 sizeof(tBuf), 0))) {
1990 if ((pagesize < 4) || tBuf[4] || tBuf[5]) {
1991 pout(
"%s failed, IE page, bad parameter code or length\n",
1996 sense_info.
asc = tBuf[8];
1997 sense_info.
ascq = tBuf[9];
1998 if (! hasTempLogPage) {
2000 *currenttemp = tBuf[10];
2002 *triptemp = tBuf[11];
2006 if (0 == sense_info.
asc) {
2015 if (hasTempLogPage) {
2016 if (0 ==
scsiGetTemp(device, &currTemp, &trTemp)) {
2017 *currenttemp = currTemp;
2028 "W: The tape drive is having problems reading data. No data has been "
2030 " but there has been a reduction in the performance of the tape.",
2032 "W: The tape drive is having problems writing data. No data has been "
2034 " but there has been a reduction in the capacity of the tape.",
2036 "W: The operation has stopped because an error has occurred while "
2038 " or writing data that the drive cannot correct.",
2040 "C: Your data is at risk:\n"
2041 " 1. Copy any data you require from this tape. \n"
2042 " 2. Do not use this tape again.\n"
2043 " 3. Restart the operation with a different tape.",
2045 "C: The tape is damaged or the drive is faulty. Call the tape drive\n"
2046 " supplier helpline.",
2048 "C: The tape is from a faulty batch or the tape drive is faulty:\n"
2049 " 1. Use a good tape to test the drive.\n"
2050 " 2. If problem persists, call the tape drive supplier helpline.",
2052 "W: The tape cartridge has reached the end of its calculated useful "
2054 " 1. Copy data you need to another tape.\n"
2055 " 2. Discard the old tape.",
2057 "W: The tape cartridge is not data-grade. Any data you back up to the "
2059 " is at risk. Replace the cartridge with a data-grade tape.",
2061 "C: You are trying to write to a write-protected cartridge. Remove the\n"
2062 " write-protection or use another tape.",
2064 "I: You cannot eject the cartridge because the tape drive is in use. "
2066 " until the operation is complete before ejecting the cartridge.",
2068 "I: The tape in the drive is a cleaning cartridge.",
2070 "I: You have tried to load a cartridge of a type which is not supported\n"
2073 "C: The operation has failed because the tape in the drive has "
2075 " a mechanical failure:\n"
2076 " 1. Discard the old tape.\n"
2077 " 2. Restart the operation with a different tape.",
2079 "C: The operation has failed because the tape in the drive has "
2081 " a mechanical failure:\n"
2082 " 1. Do not attempt to extract the tape cartridge\n"
2083 " 2. Call the tape drive supplier helpline.",
2085 "W: The memory in the tape cartridge has failed, which reduces\n"
2086 " performance. Do not use the cartridge for further write "
2089 "C: The operation has failed because the tape cartridge was manually\n"
2090 " de-mounted while the tape drive was actively writing or reading.",
2092 "W: You have loaded a cartridge of a type that is read-only in this "
2094 " The cartridge will appear as write-protected.",
2096 "W: The tape directory on the tape cartridge has been corrupted. File\n"
2097 " search performance will be degraded. The tape directory can be "
2099 " by reading all the data on the cartridge.",
2101 "I: The tape cartridge is nearing the end of its calculated life. It is\n"
2102 " recommended that you:\n"
2103 " 1. Use another tape cartridge for your next backup.\n"
2104 " 2. Store this tape in a safe place in case you need to restore "
2107 "C: The tape drive needs cleaning:\n"
2108 " 1. If the operation has stopped, eject the tape and clean the "
2110 " 2. If the operation has not stopped, wait for it to finish and "
2112 " clean the drive.\n"
2113 " Check the tape drive users manual for device specific cleaning "
2116 "W: The tape drive is due for routine cleaning:\n"
2117 " 1. Wait for the current operation to finish.\n"
2118 " 2. The use a cleaning cartridge.\n"
2119 " Check the tape drive users manual for device specific cleaning "
2122 "C: The last cleaning cartridge used in the tape drive has worn out:\n"
2123 " 1. Discard the worn out cleaning cartridge.\n"
2124 " 2. Wait for the current operation to finish.\n"
2125 " 3. Then use a new cleaning cartridge.",
2127 "C: The last cleaning cartridge used in the tape drive was an invalid\n"
2129 " 1. Do not use this cleaning cartridge in this drive.\n"
2130 " 2. Wait for the current operation to finish.\n"
2131 " 3. Then use a new cleaning cartridge.",
2133 "W: The tape drive has requested a retention operation",
2135 "W: A redundant interface port on the tape drive has failed",
2137 "W: A tape drive cooling fan has failed",
2139 "W: A redundant power supply has failed inside the tape drive enclosure.\n"
2140 " Check the enclosure users manual for instructions on replacing "
2142 " failed power supply.",
2144 "W: The tape drive power consumption is outside the specified range.",
2146 "W: Preventive maintenance of the tape drive is required. Check the tape\n"
2147 " drive users manual for device specific preventive maintenance\n"
2148 " tasks or call the tape drive supplier helpline.",
2150 "C: The tape drive has a hardware fault:\n"
2151 " 1. Eject the tape or magazine.\n"
2152 " 2. Reset the drive.\n"
2153 " 3. Restart the operation.",
2155 "C: The tape drive has a hardware fault:\n"
2156 " 1. Turn the tape drive off and then on again.\n"
2157 " 2. Restart the operation.\n"
2158 " 3. If the problem persists, call the tape drive supplier helpline.",
2160 "W: The tape drive has a problem with the application client interface:\n"
2161 " 1. Check the cables and cable connections.\n"
2162 " 2. Restart the operation.",
2164 "C: The operation has failed:\n"
2165 " 1. Eject the tape or magazine.\n"
2166 " 2. Insert the tape or magazine again.\n"
2167 " 3. Restart the operation.",
2169 "W: The firmware download has failed because you have tried to use the\n"
2170 " incorrect firmware for this tape drive. Obtain the correct\n"
2171 " firmware and try again.",
2173 "W: Environmental conditions inside the tape drive are outside the\n"
2174 " specified humidity range.",
2176 "W: Environmental conditions inside the tape drive are outside the\n"
2177 " specified temperature range.",
2179 "W: The voltage supply to the tape drive is outside the specified range.",
2181 "C: A hardware failure of the tape drive is predicted. Call the tape\n"
2182 " drive supplier helpline.",
2184 "W: The tape drive may have a hardware fault. Run extended diagnostics to\n"
2185 " verify and diagnose the problem. Check the tape drive users manual "
2187 " device specific instructions on running extended diagnostic tests.",
2189 "C: The changer mechanism is having difficulty communicating with the "
2192 " 1. Turn the autoloader off then on.\n"
2193 " 2. Restart the operation.\n"
2194 " 3. If problem persists, call the tape drive supplier helpline.",
2196 "C: A tape has been left in the autoloader by a previous hardware fault:\n"
2197 " 1. Insert an empty magazine to clear the fault.\n"
2198 " 2. If the fault does not clear, turn the autoloader off and then\n"
2200 " 3. If the problem persists, call the tape drive supplier helpline.",
2202 "W: There is a problem with the autoloader mechanism.",
2204 "C: The operation has failed because the autoloader door is open:\n"
2205 " 1. Clear any obstructions from the autoloader door.\n"
2206 " 2. Eject the magazine and then insert it again.\n"
2207 " 3. If the fault does not clear, turn the autoloader off and then\n"
2209 " 4. If the problem persists, call the tape drive supplier helpline.",
2211 "C: The autoloader has a hardware fault:\n"
2212 " 1. Turn the autoloader off and then on again.\n"
2213 " 2. Restart the operation.\n"
2214 " 3. If the problem persists, call the tape drive supplier helpline.\n"
2215 " Check the autoloader users manual for device specific instructions\n"
2216 " on turning the device power on and off.",
2218 "C: The autoloader cannot operate without the magazine,\n"
2219 " 1. Insert the magazine into the autoloader.\n"
2220 " 2. Restart the operation.",
2222 "W: A hardware failure of the changer mechanism is predicted. Call the\n"
2223 " tape drive supplier helpline.",
2231 "W: Media statistics have been lost at some time in the past",
2233 "W: The tape directory on the tape cartridge just unloaded has been\n"
2234 " corrupted. File search performance will be degraded. The tape\n"
2235 " directory can be rebuilt by reading all the data.",
2237 "C: The tape just unloaded could not write its system area successfully:\n"
2238 " 1. Copy data to another tape cartridge.\n"
2239 " 2. Discard the old cartridge.",
2241 "C: The tape system are could not be read successfully at load time:\n"
2242 " 1. Copy data to another tape cartridge.\n",
2244 "C: The start or data could not be found on the tape:\n"
2245 " 1. Check you are using the correct format tape.\n"
2246 " 2. Discard the tape or return the tape to your supplier",
2248 "C: The operation has failed because the media cannot be loaded\n"
2250 " 1. Remove the cartridge, inspect it as specified in the product\n"
2251 " manual, and retry the operation.\n"
2252 " 2. If the problem persists, call the tape drive supplier help "
2255 "C: The operation has failed because the medium cannot be unloaded:\n"
2256 " 1. Do not attempt to extract the tape cartridge.\n"
2257 " 2. Call the tape driver supplier help line.",
2259 "C: The tape drive has a problem with the automation interface:\n"
2260 " 1. Check the power to the automation system.\n"
2261 " 2. Check the cables and cable connections.\n"
2262 " 3. Call the supplier help line if problem persists.",
2264 "W: The tape drive has reset itself due to a detected firmware\n"
2265 " fault. If problem persists, call the supplier help line.",
2281 "C: The library mechanism is having difficulty communicating with the\n"
2283 " 1. Turn the library off then on.\n"
2284 " 2. Restart the operation.\n"
2285 " 3. If the problem persists, call the library supplier help line.",
2287 "W: There is a problem with the library mechanism. If problem persists,\n"
2288 " call the library supplier help line.",
2290 "C: The library has a hardware fault:\n"
2291 " 1. Reset the library.\n"
2292 " 2. Restart the operation.\n"
2293 " Check the library users manual for device specific instructions on "
2297 "C: The library has a hardware fault:\n"
2298 " 1. Turn the library off then on again.\n"
2299 " 2. Restart the operation.\n"
2300 " 3. If the problem persists, call the library supplier help line.\n"
2301 " Check the library users manual for device specific instructions on "
2303 " device power on and off.",
2305 "W: The library mechanism may have a hardware fault.\n"
2306 " Run extended diagnostics to verify and diagnose the problem. "
2307 "Check the library\n"
2308 " users manual for device specific instructions on running extended "
2312 "C: The library has a problem with the host interface:\n"
2313 " 1. Check the cables and connections.\n"
2314 " 2. Restart the operation.",
2316 "W: A hardware failure of the library is predicted. Call the library\n"
2317 " supplier help line.",
2319 "W: Preventive maintenance of the library is required.\n"
2320 " Check the library users manual for device specific preventative "
2322 " tasks, or call your library supplier help line.",
2324 "C: General environmental conditions inside the library are outside the\n"
2325 " specified humidity range.",
2327 "C: General environmental conditions inside the library are outside the\n"
2328 " specified temperature range.",
2330 "C: The voltage supply to the library is outside the specified range.\n"
2331 " There is a potential problem with the power supply or failure of\n"
2332 " a redundant power supply.",
2334 "C: A cartridge has been left inside the library by a previous hardware\n"
2336 " 1. Insert an empty magazine to clear the fault.\n"
2337 " 2. If the fault does not clear, turn the library off and then on "
2339 " 3. If the problem persists, call the library supplier help line.",
2341 "W: There is a potential problem with the drive ejecting cartridges or\n"
2342 " with the library mechanism picking a cartridge from a slot.\n"
2343 " 1. No action needs to be taken at this time.\n"
2344 " 2. If the problem persists, call the library supplier help line.",
2346 "W: There is a potential problem with the library mechanism placing a\n"
2347 " cartridge into a slot.\n"
2348 " 1. No action needs to be taken at this time.\n"
2349 " 2. If the problem persists, call the library supplier help line.",
2351 "W: There is a potential problem with the drive or the library mechanism\n"
2352 " loading cartridges, or an incompatible cartridge.",
2354 "C: The library has failed because the door is open:\n"
2355 " 1. Clear any obstructions from the library door.\n"
2356 " 2. Close the library door.\n"
2357 " 3. If the problem persists, call the library supplier help line.",
2359 "C: There is a mechanical problem with the library media import/export\n"
2362 "C: The library cannot operate without the magazine.\n"
2363 " 1. Insert the magazine into the library.\n"
2364 " 2. Restart the operation.",
2366 "W: Library security has been compromised.",
2368 "I: The library security mode has been changed.\n"
2369 " The library has either been put into secure mode, or the library "
2371 " the secure mode.\n"
2372 " This is for information purposes only. No action is required.",
2374 "I: The library has been manually turned offline and is unavailable for "
2377 "I: A drive inside the library has been taken offline.\n"
2378 " This is for information purposes only. No action is required.",
2380 "W: There is a potential problem with the bar code label or the scanner\n"
2381 " hardware in the library mechanism.\n"
2382 " 1. No action needs to be taken at this time.\n"
2383 " 2. If the problem persists, call the library supplier help line.",
2385 "C: The library has detected an inconsistency in its inventory.\n"
2386 " 1. Redo the library inventory to correct inconsistency.\n"
2387 " 2. Restart the operation.\n"
2388 " Check the applications users manual or the hardware users manual "
2390 " specific instructions on redoing the library inventory.",
2392 "W: A library operation has been attempted that is invalid at this time.",
2394 "W: A redundant interface port on the library has failed.",
2396 "W: A library cooling fan has failed.",
2398 "W: A redundant power supply has failed inside the library. Check the\n"
2399 " library users manual for instructions on replacing the failed "
2402 "W: The library power consumption is outside the specified range.",
2404 "C: A failure has occurred in the cartridge pass-through mechanism "
2406 " two library modules.",
2408 "C: A cartridge has been left in the pass-through mechanism from a\n"
2409 " previous hardware fault. Check the library users guide for "
2411 " clearing this fault.",
2413 "I: The library was unable to read the bar code on a cartridge.",
2455 pout(
"Long (extended) offline self test failed [%s]\n",
2478 pout(
"Long (extended) foreground self test failed [%s]\n",
2501 uint8_t buff[64] = {};
2506 buff,
sizeof(buff)))) {
2517 buff,
sizeof(buff));
2524 if (buff[offset + 1] >= 0xa) {
2540 *durationSec = res * 60;
2552 memset(ecp, 0,
sizeof(*ecp));
2554 unsigned char * ucp = &resp[0] + 4;
2557 num = num < allocLen - 4 ? num : allocLen - 4;
2560 int pl = ucp[3] + 4;
2582 unsigned char * xp = ucp + 4;
2583 if (k > (
int)
sizeof(*ullp)) {
2584 xp += (k -
sizeof(*ullp));
2598 memset(nmep, 0,
sizeof(*nmep));
2600 unsigned char * ucp = &resp[0] + 4;
2604 num = num < allocLen - 4 ? num : allocLen - 4;
2607 int pl = ucp[3] + 4;
2664 int num, k, err, fails, fail_hour;
2684 pout(
"Self-test %s length is 0x%x not 0x190 bytes\n",
logSenStr,
2691 for (k = 0, ucp = resp + 4; k < 20; ++k, ucp += 20 ) {
2698 if ((0 == n) && (0 == ucp[4]))
2700 int res = ucp[4] & 0xf;
2701 if ((res > 2) && (res < 8)) {
2707 return (fail_hour << 8) + fails;
2732 *inProgress = (0xf == (ucp[4] & 0xf)) ? 1 : 0;
2744 uint8_t buff[64] = {};
2749 buff,
sizeof(buff)))) {
2759 buff,
sizeof(buff));
2764 if ((offset >= 0) && (buff[offset + 1] >= 0xa))
2765 return (buff[offset + 2] & 2) ? 1 : 0;
2782 uint8_t buff[64] = {};
2786 buff,
sizeof(buff))) &&
2790 *form_factorp = buff[7] & 0xf;
2792 *haw_zbcp = (buff[8] >> 4) & 0x3;
2801 buff,
sizeof(buff)))) {
2811 buff,
sizeof(buff));
2826 int err, offset, resp_len, sp;
2827 uint8_t buff[64] = {};
2828 uint8_t ch_buff[64];
2829 short set_wce = *wcep;
2830 short set_rcd = *rcdp;
2834 buff,
sizeof(buff));
2839 device->
set_err(EINVAL,
"SCSI MODE SENSE failed");
2848 buff,
sizeof(buff));
2850 device->
set_err(EINVAL,
"SCSI MODE SENSE failed");
2855 if ((offset < 0) || (buff[offset + 1] < 0xa)) {
2856 device->
set_err(EINVAL,
"Bad response");
2860 *wcep = ((buff[offset + 2] & 0x04) != 0);
2861 *rcdp = ((buff[offset + 2] & 0x01) != 0);
2863 if((*wcep == set_wce || set_wce == -1)
2864 && ((*rcdp == set_rcd) || set_rcd == -1))
2870 ch_buff,
sizeof(ch_buff));
2874 ch_buff,
sizeof(ch_buff));
2876 device->
set_err(EINVAL,
"WCE/RCD bits not changeable");
2881 if(set_wce >= 0 && *wcep != set_wce) {
2882 if (0 == (ch_buff[offset + 2] & 0x04)) {
2883 device->
set_err(EINVAL,
"WCE bit not changeable");
2887 buff[offset + 2] |= 0x04;
2889 buff[offset + 2] &= 0xfb;
2892 if(set_rcd >= 0 && *rcdp != set_rcd) {
2893 if (0 == (ch_buff[offset + 2] & 0x01)) {
2894 device->
set_err(EINVAL,
"RCD bit not changeable");
2898 buff[offset + 2] |= 0x01;
2900 buff[offset + 2] &= 0xfe;
2908 resp_len = buff[0] + 1;
2917 device->
set_err(EINVAL,
"MODE SELECT command failed");
2929 int err, offset, resp_len, sp;
2930 uint8_t buff[64] = {};
2931 uint8_t ch_buff[64];
2936 buff,
sizeof(buff)))) {
2947 buff,
sizeof(buff));
2952 if ((offset < 0) || (buff[offset + 1] < 0xa))
2957 if (enabled == (buff[offset + 2] & 2))
2963 ch_buff,
sizeof(ch_buff));
2967 ch_buff,
sizeof(ch_buff));
2970 if (0 == (ch_buff[offset + 2] & 2))
2978 resp_len = buff[0] + 1;
2981 sp = (buff[offset] & 0x80) ? 1 : 0;
2983 buff[offset + 2] |= 0x2;
2985 buff[offset + 2] &= 0xfd;
3000 uint8_t buff[64] {};
3005 buff,
sizeof(buff)))) {
3016 buff,
sizeof(buff));
3021 if ((offset >= 0) && (buff[offset + 1] > 1)) {
3022 if ((0 == (buff[offset] & 0x40)) &&
3024 return (buff[offset + 2] & 0xf);
3029const unsigned char *
3034 const unsigned char * descp;
3036 if ((
sense_len < 8) || (0 == (add_sen_len = sensep[7])))
3038 if ((sensep[0] < 0x72) || (sensep[0] > 0x73))
3040 add_sen_len = (add_sen_len < (
sense_len - 8)) ?
3043 for (
int desc_len = 0, k = 0; k < add_sen_len; k += desc_len) {
3045 int add_len = (k < (add_sen_len - 1)) ? descp[1]: -1;
3046 desc_len = add_len + 2;
3047 if (descp[0] == desc_type)
3060 n = n > 64 ? 64 : n;
3061 strncpy(tmp, (
const char *)in, n);
3067 for (i = 0; tmp[i]; i++)
3068 if (!isspace((
int)tmp[i])) {
3080 for (i = strlen(tmp)-1; i >= first && isspace((
int)tmp[i]); i--);
3083 strncpy(out, tmp+first, last-first+1);
3084 out[last-first+1] =
'\0';
3087static const char *
wn =
"Warning";
3090 "specified temperature exceeded",
3091 "enclosure degraded",
3092 "background self-test failed",
3093 "background pre-scan detected medium error",
3094 "background medium scan detected medium error",
3095 "non-volatile cache now volatile",
3096 "degraded power to non-volatile cache",
3097 "power loss expected",
3098 "device statistics notification active",
3113 "general hard drive failure",
3114 "drive error rate too high",
3115 "data error rate too high",
3116 "seek error rate too high",
3117 "too many block reassigns",
3118 "access times too high",
3119 "start unit times too high",
3120 "channel parametrics",
3121 "controller detected",
3122 "throughput performance",
3123 "seek time performance",
3124 "spin-up retry count",
3125 "drive calibration retry count",
3128static const char *
pred =
"prediction threshold exceeded";
3143 snprintf(
b, blen,
"%s",
wn);
3157 snprintf(
b, blen,
"%s - microcode security at risk",
wn);
3160 snprintf(
b, blen,
"%s - microcode digital signature validation "
3164 snprintf(
b, blen,
"%s - physical element status change",
wn);
3167 if ((
ascq >= 0xa) && (
ascq <= 0x11)) {
3168 uint8_t q =
ascq - 0xa;
3170 snprintf(
b, blen,
"%s - %s %s %s limit exceeded",
wn,
3171 (((q % 2) == 0) ?
"high" :
"low"),
3172 ((((q / 2) % 2) == 0) ?
"critical" :
"operating"),
3173 ((((q / 4) % 2) == 0) ?
"temperature" :
"humidity"));
3178 }
else if (
asc == 0x5d) {
3181 snprintf(
b, blen,
"Failure %s",
pred);
3184 snprintf(
b, blen,
"Media failure %s",
pred);
3187 snprintf(
b, blen,
"Logical unit failure %s",
pred);
3190 snprintf(
b, blen,
"spare area exhaustion failure %s",
pred);
3193 snprintf(
b, blen,
"%s %s power loss protection circuit area "
3197 snprintf(
b, blen,
"Media %s endurance limit met",
impfail);
3200 snprintf(
b, blen,
"Failure %s (false)",
pred);
3203 if ((
ascq >= 0x10) && (
ascq <= 0x6c)) {
3204 uint8_t q =
ascq - 0x10;
3205 uint8_t rem = q % 0x10;
bool is_spc4_or_higher() const
scsi_cmd_support rdefect12_sup
void set_rcap16_first()
Always try READ CAPACITY(10) (rcap10) first but once we know rcap16 is needed, use it instead.
scsi_cmd_support rsoc_sup
virtual bool scsi_pass_through(scsi_cmnd_io *iop)=0
SCSI pass through.
enum scsi_cmd_support cmd_support_level(uint8_t opcode, bool sa_valid, uint16_t sa) const
scsi_cmd_support rdefect10_sup
scsi_cmd_support rcap16_sup
void set_spc4_or_higher()
int get_errno() const
Get last error number.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
bool is_supported(int vpd_page_num) const
supported_vpd_pages(scsi_device *device)
int scsiSetPowerCondition(scsi_device *device, int power_cond, int pcond_modifier)
int scsiReadDefect12(scsi_device *device, int req_plist, int req_glist, int dl_format, int addrDescIndex, uint8_t *pBuf, int bufLen)
int scsiFetchExtendedSelfTestTime(scsi_device *device, int *durationSec, int modese_len)
void scsiDecodeErrCounterPage(unsigned char *resp, struct scsiErrorCounter *ecp, int allocLen)
int scsiModeSelect(scsi_device *device, int sp, uint8_t *pBuf, int bufLen)
int scsiSimpleSenseFilter(const struct scsi_sense_disect *sinfo)
#define RSOC_ALL_BYTES_CTDP_0
#define SCSI_IEC_MP_BYTE2_ENABLED
int scsiSetExceptionControlAndWarning(scsi_device *device, int enabled, const struct scsi_iec_mode_page *iecp)
static struct scsi_sa_var_map sa_var_a[]
int scsiSmartExtendCapSelfTest(scsi_device *device)
static const char * TapeAlertsMessageTable[]
int scsiFetchIECmpage(scsi_device *device, struct scsi_iec_mode_page *iecp, int modese_len)
int scsiGetTemp(scsi_device *device, uint8_t *currenttemp, uint8_t *triptemp)
int scsiSmartShortCapSelfTest(scsi_device *device)
int scsiSmartSelfTestAbort(scsi_device *device)
char * scsi_get_sense_key_str(int sense_key, int buff_len, char *buff)
static const char * ChangerTapeAlertsMessageTable[]
static const char * impfail
const char * scsiTapeAlertsTapeDevice(unsigned short code)
int scsiFetchTransportProtocol(scsi_device *device, int modese_len)
int scsi_decode_lu_dev_id(const unsigned char *b, int blen, char *s, int slen, int *transport)
bool is_scsi_cdb(const uint8_t *cdbp, int clen)
static const char * wn1_9[]
void dStrHexFp(const uint8_t *up, int len, int no_ascii, FILE *fp)
int scsiTestUnitReady(scsi_device *device)
int scsiModeSense10(scsi_device *device, int pagenum, int subpagenum, int pc, uint8_t *pBuf, int bufLen)
int scsiModePageOffset(const uint8_t *resp, int len, int modese_len)
void scsi_do_sense_disect(const struct scsi_cmnd_io *io_buf, struct scsi_sense_disect *out)
int scsiInquiryVpd(scsi_device *device, int vpd_page, uint8_t *pBuf, int bufLen)
static void dStrHexHelper(const uint8_t *up, int len, int no_ascii, void(*out)(const char *s, void *ctx), void *ctx=nullptr)
#define SCSI_IEC_MP_REPORT_COUNT
static int trimTrailingSpaces(char *b)
int scsiSmartExtendSelfTest(scsi_device *device)
#define RSOC_ALL_BYTES_CTDP_1
void scsiDecodeNonMediumErrPage(unsigned char *resp, struct scsiNonMediumError *nmep, int allocLen)
int scsiRequestSense(scsi_device *device, struct scsi_sense_disect *sense_info)
int scsiCheckIE(scsi_device *device, int hasIELogPage, int hasTempLogPage, uint8_t *asc, uint8_t *ascq, uint8_t *currenttemp, uint8_t *triptemp)
const char * scsicmds_c_cvsid
uint64_t scsiGetSize(scsi_device *device, bool avoid_rcap16, struct scsi_readcap_resp *srrp)
int scsiSelfTestInProgress(scsi_device *fd, int *inProgress)
static const char * sense_key_desc[]
char * scsiGetIEString(uint8_t asc, uint8_t ascq, char *b, int blen)
static const char * vendor_specific
int scsiGetSetCache(scsi_device *device, int modese_len, short int *wcep, short int *rcdp)
#define SCSI_IEC_MP_INTERVAL_T
supported_vpd_pages * supported_vpd_pages_p
bool scsi_pass_through_yield_sense(scsi_device *device, scsi_cmnd_io *iop, scsi_sense_disect &sinfo)
int scsiGetRPM(scsi_device *device, int modese_len, int *form_factorp, int *haw_zbcp)
void scsi_format_id_string(char *out, const uint8_t *in, int n)
int scsiReadCapacity16(scsi_device *device, uint8_t *pBuf, int bufLen)
int scsiStdInquiry(scsi_device *device, uint8_t *pBuf, int bufLen)
int scsiModeSelect10(scsi_device *device, int sp, uint8_t *pBuf, int bufLen)
const unsigned char * sg_scsi_sense_desc_find(const unsigned char *sensep, int sense_len, int desc_type)
static const char * logSenStr
#define SCSI_IEC_MP_BYTE2_TEST_MASK
int scsiSmartDefaultSelfTest(scsi_device *device)
static int _testunitready(scsi_device *device, struct scsi_sense_disect *sinfop)
void dStrHex(const uint8_t *up, int len, int no_ascii)
int scsiSendDiagnostic(scsi_device *device, int functioncode, uint8_t *pBuf, int bufLen)
const char * scsiErrString(int scsiErr)
const char * scsiTapeAlertsChangerDevice(unsigned short code)
int scsiReadCapacity10(scsi_device *device, unsigned int *last_lbap, unsigned int *lb_sizep)
int scsiFetchControlGLTSD(scsi_device *device, int modese_len, int current)
int scsiRSOCcmd(scsi_device *device, uint8_t *pBuf, int bufLen, int &rspLen)
static int my_isprint(uint8_t ch)
static struct scsi_opcode_name opcode_name_arr[]
int scsiModeSense(scsi_device *device, int pagenum, int subpagenum, int pc, uint8_t *pBuf, int bufLen)
int scsiCountFailedSelfTests(scsi_device *fd, int noisy)
int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp)
int scsiSetControlGLTSD(scsi_device *device, int enabled, int modese_len)
int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp)
int scsiSmartShortSelfTest(scsi_device *device)
int scsiLogSense(scsi_device *device, int pagenum, int subpagenum, uint8_t *pBuf, int bufLen, int known_resp_len)
unsigned char scsi_debugmode
const char * scsi_get_opcode_name(const uint8_t *cdbp)
int scsiLogSelect(scsi_device *device, int pcr, int sp, int pc, int pagenum, int subpagenum, uint8_t *pBuf, int bufLen)
static const char * five_d_t[]
int scsiReadDefect10(scsi_device *device, int req_plist, int req_glist, int dl_format, uint8_t *pBuf, int bufLen)
static const char * impending0_c[]
int scsi_vpd_dev_id_iter(const unsigned char *initial_desig_desc, int page_len, int *off, int m_assoc, int m_desig_type, int m_code_set)
#define SIMPLE_ERR_BECOMING_READY
#define SCSI_SK_MEDIUM_ERROR
#define SIMPLE_ERR_MEDIUM_HARDWARE
#define MPAGE_CONTROL_CURRENT
#define SAI_READ_CAPACITY_16
#define SCSI_ASC_UNKNOWN_OPCODE
#define SIMPLE_ERR_BAD_FIELD
#define SAI_GET_PHY_ELEM_STATUS
#define INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE
#define MAINTENANCE_IN_12
#define SCSI_DIAG_DEF_SELF_TEST
#define SCSI_SK_UNIT_ATTENTION
#define MI_REP_SUP_OPCODES
#define SAT_ATA_PASSTHROUGH_12
#define SIMPLE_ERR_NOT_READY
#define RIGID_DISK_DRIVE_GEOMETRY_PAGE
#define SCSI_DIAG_BG_SHORT_SELF_TEST
#define SIMPLE_ERR_ABORTED_COMMAND
#define SCSI_VPD_BLOCK_DEVICE_CHARACTERISTICS
#define SCSI_DIAG_BG_EXTENDED_SELF_TEST
#define SIMPLE_ERR_TRY_AGAIN
#define SIMPLE_ERR_NO_MEDIUM
#define RECEIVE_DIAGNOSTIC
#define SCSI_ASC_INVALID_FIELD
int scsiInquiryVpd(scsi_device *device, int vpd_page, uint8_t *pBuf, int bufLen)
#define SELFTEST_RESULTS_LPAGE
#define SIMPLE_ERR_PROTECTION
#define DXFER_FROM_DEVICE
#define SCSI_SK_ILLEGAL_REQUEST
#define SCSI_TIMEOUT_DEFAULT
#define SCSI_SK_ABORTED_COMMAND
#define SCSI_IECMP_RAW_LEN
#define SCSI_DIAG_ABORT_SELF_TEST
#define SCSI_SK_COMPLETED
#define SAT_ATA_PASSTHROUGH_16
#define SCSI_DIAG_FG_SHORT_SELF_TEST
#define SIMPLE_ERR_BAD_OPCODE
#define SCSI_PT_MEDIUM_CHANGER
#define SCSI_ASC_UNKNOWN_PARAM
#define SCSI_PT_SEQUENTIAL_ACCESS
#define SCSI_SK_HARDWARE_ERROR
#define SCSI_STATUS_CHECK_CONDITION
#define SIMPLE_ERR_BAD_PARAM
#define SCSI_PT_HOST_MANAGED
#define MPAGE_CONTROL_DEFAULT
#define SCSI_VPD_EXTENDED_INQUIRY_DATA
#define SCSI_DIAG_NO_SELF_TEST
#define LOG_RESP_SELF_TEST_LEN
#define SCSI_VPD_SUPPORTED_VPD_PAGES
#define SIMPLE_ERR_MISCOMPARE
#define TEMPERATURE_LPAGE
#define MPAGE_CONTROL_CHANGEABLE
#define SIMPLE_ERR_BAD_RESP
#define SCSI_PT_DIRECT_ACCESS
#define SERVICE_ACTION_IN_16
#define SCSI_ASC_NOT_READY
#define SIMPLE_ERR_UNKNOWN
#define SCSI_SK_RECOVERED_ERR
#define SCSI_SK_NOT_READY
#define CONTROL_MODE_PAGE
#define SCSI_SK_DATA_PROTECT
#define SCSI_SK_MISCOMPARE
#define SCSI_DIAG_FG_EXTENDED_SELF_TEST
#define SCSI_TIMEOUT_SELF_TEST
#define SCSI_ASC_NO_MEDIUM
#define PROTOCOL_SPECIFIC_PORT_PAGE
static void sg_put_unaligned_be32(uint32_t val, void *p)
static void sg_put_unaligned_be16(uint16_t val, void *p)
static uint64_t sg_get_unaligned_be64(const void *p)
static uint64_t sg_get_unaligned_be(int num_bytes, const void *p)
static uint16_t sg_get_unaligned_be16(const void *p)
static uint32_t sg_get_unaligned_be32(const void *p)
for(char *p=buf, *q;p &&*p;p=q)
void pout(const char *fmt,...)
uint8_t raw_curr[SCSI_IECMP_RAW_LEN]
uint8_t raw_chg[SCSI_IECMP_RAW_LEN]
uint8_t requestedChangeable