49#define RSOC_RESP_SZ 4096
50#define RSOC_ALL_CMDS_CTDP_0 8
51#define RSOC_ALL_CMDS_CTDP_1 20
52#define RSOC_1_CMD_CTDP_0 36
61 uint8_t * rp = rsoc_1cmd_rsp;
72 pout(
"%s response to short [%d]\n", __func__, r_len);
83 int k, err, cd_len, bump;
85 uint8_t * rp = (uint8_t *)calloc(
sizeof(uint8_t),
RSOC_RESP_SZ);
86 const uint8_t * last_rp;
104 pout(
"%s response too short\n", __func__);
110 if (cd_len > max_bytes_of_cmds) {
112 pout(
"%s: truncate %d byte response to %d bytes\n", __func__,
113 cd_len, max_bytes_of_cmds);
114 cd_len = max_bytes_of_cmds;
116 last_rp = rp + cd_len;
123 for (k = 0, cmdp = rp + 4; cmdp < last_rp; ++k, cmdp += bump) {
124 bool sa_valid = !! (0x1 & cmdp[5]);
125 bool ctdp = !! (0x2 & cmdp[5]);
152 pout(
"%s: decoded %d supported commands\n", __func__, k);
153 pout(
" LOG SENSE %ssupported\n",
155 pout(
" LOG SENSE subpage code %ssupported\n",
157 pout(
" READ DEFECT 10 %ssupported\n",
159 pout(
" READ DEFECT 12 %ssupported\n",
161 pout(
" READ CAPACITY 16 %ssupported\n",
173 uint16_t sa,
bool for_lsense_spc)
const
203 unsigned char b[0xfc] = {};
208 int n =
sizeof(
b) - 4;
221 if (vpd_page_num ==
pages[k])
232 return ((ch >=
' ') && (ch < 0x7f));
240 while ((n > 0) && (
' ' ==
b[n - 1]))
249 void (*out)(
const char *
s,
void * ctx),
void * ctx =
nullptr)
251 static const int line_len = 80;
252 static const int cpstart = 60;
254 char buff[line_len + 2];
260 char e[line_len + 4];
261 static const int elen =
sizeof(e);
265 blen = (int)
sizeof(buff);
266 memset(buff,
' ', line_len);
267 buff[line_len] =
'\0';
271 for (k = 0; k < len; k++) {
273 if (bpos == (bpstart + (8 * 3)))
275 snprintf(&buff[bpos], blen - bpos,
"%.2x", (
int)(uint8_t)c);
276 buff[bpos + 2] =
' ';
277 if ((k > 0) && (0 == ((k + 1) % 16))) {
280 snprintf(e, elen,
"%s\n", buff);
282 snprintf(e, elen,
"%.76s\n", buff);
285 memset(buff,
' ', line_len);
289 if (bpos > bpstart) {
290 buff[bpos + 2] =
'\0';
292 snprintf(e, elen,
"%s\n", buff);
298 k = snprintf(buff + 1, blen - 1,
"%.2x", a);
301 for (i = 0; i < len; i++) {
304 if (bpos == (bpstart + (9 * 3)))
306 snprintf(&buff[bpos], blen - bpos,
"%.2x", (
int)(uint8_t)c);
307 buff[bpos + 2] =
' ';
315 if (cpos > (cpstart + 15)) {
319 snprintf(e, elen,
"%s\n", buff);
321 snprintf(e, elen,
"%.76s\n", buff);
326 memset(buff,
' ', line_len);
327 k = snprintf(buff + 1, blen - 1,
"%.2x", a);
331 if (cpos > cpstart) {
335 snprintf(e, elen,
"%s\n", buff);
344dStrHexFp(
const uint8_t * up,
int len,
int no_ascii, FILE * fp)
347 if ((
nullptr == up) || (len < 1))
351 [](
const char *
s,
void * ctx)
352 { fputs(
s,
reinterpret_cast<FILE *
>(ctx)); },
356 [](
const char *
s,
void *){
pout(
"%s",
s); });
368dStrHex(
const uint8_t * up,
int len,
int no_ascii)
372 [](
const char *
s,
void *){
pout(
"%s",
s); });
396 uint8_t top3bits =
opcode >> 5;
397 if (0x3 == top3bits) {
399 if ((clen < 12) || (clen % 4))
404 return (ilen == clen);
409 return ((ilen == clen) && sa);
413 }
else if (clen <= 16) {
418 return (0x0 == top3bits);
422 return ((0x1 == top3bits) || (0x2 == top3bits));
426 return (0x4 == top3bits);
430 return (0x5 == top3bits);
482 {
INQUIRY,
false, 0,
"inquiry"},
498 "get physical element status"},
502 "report supported operation codes"},
519 static const int sa_var_len =
sizeof(
sa_var_a) /
526 for (k = 0; k < sa_var_len; ++k) {
547 for (k = 0; k < len; ++k) {
558 }
else if (opcode < onp->
opcode)
570 int resp_code = (io_buf->
sensep[0] & 0x7f);
572 if (resp_code >= 0x72) {
576 }
else if (resp_code >= 0x70) {
598 if (0x1 == sinfo->
ascq)
633 return strerror(-scsiErr);
638 return "device not ready";
640 return "unsupported scsi opcode";
642 return "unsupported field in scsi command";
644 return "badly formed scsi parameters";
646 return "scsi response fails sanity test";
648 return "no medium present";
650 return "device will be ready soon";
652 return "unit attention reported, try again";
654 return "medium or hardware error (serious)";
656 return "unknown error (unexpected sense key)";
658 return "aborted command";
660 return "data protection error";
664 return "unknown error";
683 "Vendor specific(9)",
701 if ((sense_key >= 0) && (sense_key < 16))
704 snprintf(buff, buff_len,
"invalid value: 0x%x", sense_key);
719 int * off,
int m_assoc,
int m_desig_type,
int m_code_set)
721 const unsigned char * ucp;
724 for (k = *off, ucp = initial_desig_desc ; (k + 3) < page_len; ) {
725 k = (k < 0) ? 0 : (k + ucp[k + 3] + 4);
726 if ((k + 4) > page_len)
728 int c_set = (ucp[k] & 0xf);
729 if ((m_code_set >= 0) && (m_code_set != c_set))
731 int assoc = ((ucp[k + 1] >> 4) & 0x3);
732 if ((m_assoc >= 0) && (m_assoc != assoc))
734 int desig_type = (ucp[k + 1] & 0xf);
735 if ((m_desig_type >= 0) && (m_desig_type != desig_type))
740 return (k == page_len) ? -1 : -2;
759#define SLEN(a, b) ((a) > (b) ? ((a) - (b)) : 0)
762 int have_scsi_ns = 0, have_eui_64 = 0, have_naa = 0;
766 const unsigned char * ucp =
b + off;
768 if ((off + i_len + 4) > blen) {
769 snprintf(
s+si,
SLEN(slen, si),
"error: designator length");
772 int assoc = ((ucp[1] >> 4) & 0x3);
773 if (transport && assoc && (ucp[1] & 0x80) && (*transport < 0))
774 *transport = (ucp[0] >> 4) & 0xf;
777 const unsigned char * ip = ucp + 4;
778 int c_set = (ucp[0] & 0xf);
779 int desig_type = (ucp[1] & 0xf);
782 switch (desig_type) {
787 if ((8 != i_len) && (12 != i_len) && (16 != i_len)) {
788 snprintf(
s+si,
SLEN(slen, si),
"error: EUI-64 length");
792 snprintf(
s+si,
SLEN(slen, si),
"error: Duplicate EUI-64 designator");
799 si += snprintf(
s+si,
SLEN(slen, si),
"0x");
800 for (
int m = 0; m < i_len; ++m)
801 si += snprintf(
s+si,
SLEN(slen, si),
"%02x", (
unsigned int)ip[m]);
806 snprintf(
s+si,
SLEN(slen, si),
"error: NAA bad code_set");
809 naa = (ip[0] >> 4) & 0xff;
810 if ((naa < 2) || (naa > 6) || (4 == naa)) {
811 snprintf(
s+si,
SLEN(slen, si),
"error: unexpected NAA");
815 snprintf(
s+si,
SLEN(slen, si),
"error: Duplicate NAA designator");
818 if (have_eui_64 || have_scsi_ns)
822 snprintf(
s+si,
SLEN(slen, si),
"error: NAA 2 length");
825 si += snprintf(
s+si,
SLEN(slen, si),
"0x");
826 for (
int m = 0; m < 8; ++m)
827 si += snprintf(
s+si,
SLEN(slen, si),
"%02x", (
unsigned int)ip[m]);
828 }
else if ((3 == naa ) || (5 == naa)) {
831 snprintf(
s+si,
SLEN(slen, si),
"error: NAA 3 or 5 length");
834 si += snprintf(
s+si,
SLEN(slen, si),
"0x");
835 for (
int m = 0; m < 8; ++m)
836 si += snprintf(
s+si,
SLEN(slen, si),
"%02x", (
unsigned int)ip[m]);
837 }
else if (6 == naa) {
839 snprintf(
s+si,
SLEN(slen, si),
"error: NAA 6 length");
842 si += snprintf(
s+si,
SLEN(slen, si),
"0x");
843 for (
int m = 0; m < 16; ++m)
844 si += snprintf(
s+si,
SLEN(slen, si),
"%02x", (
unsigned int)ip[m]);
855 snprintf(
s+si,
SLEN(slen, si),
"error: SCSI name string");
859 snprintf(
s+si,
SLEN(slen, si),
"error: Duplicate SCSI name string designator");
862 if (have_eui_64 || have_naa)
865 si += snprintf(
s+si,
SLEN(slen, si),
"%s", (
const char *)ip);
873 snprintf(
s+si,
SLEN(slen, si),
"error: bad structure");
893 int bufLen,
int known_resp_len)
898 uint8_t
cdb[10] = {};
901 if (known_resp_len > bufLen)
903 if (known_resp_len > 0)
904 pageLen = known_resp_len;
905 else if (known_resp_len < 0)
910 if (pageLen > bufLen)
913 memset(pBuf, 0, pageLen);
919 cdb[2] = 0x40 | (pagenum & 0x3f);
943 if (pageLen > bufLen)
947 memset(&io_hdr, 0,
sizeof(io_hdr));
948 memset(
cdb, 0,
sizeof(
cdb));
953 cdb[2] = 0x40 | (pagenum & 0x3f);
982 int subpagenum, uint8_t *pBuf,
int bufLen)
986 uint8_t
cdb[10] = {};
993 cdb[1] = (pcr ? 2 : 0) | (sp ? 1 : 0);
994 cdb[2] = ((pc << 6) & 0xc0) | (pagenum & 0x3f);
995 cdb[3] = (subpagenum & 0xff);
1014 uint8_t *pBuf,
int bufLen)
1018 uint8_t
cdb[6] = {};
1021 if ((bufLen < 0) || (bufLen > 255))
1027 cdb[2] = (pc << 6) | (pagenum & 0x3f);
1028 cdb[3] = subpagenum;
1045 else if (pagenum != (pBuf[offset] & 0x3f))
1063 uint8_t
cdb[6] = {};
1065 int pg_offset, pg_len, hdr_plus_1_pg;
1067 pg_offset = 4 + pBuf[3];
1068 if (pg_offset + 2 >= bufLen)
1070 pg_len = pBuf[pg_offset + 1] + 2;
1071 hdr_plus_1_pg = pg_offset + pg_len;
1072 if (hdr_plus_1_pg > bufLen)
1075 pBuf[pg_offset] &= 0x7f;
1080 cdb[1] = 0x10 | (sp & 1);
1081 cdb[4] = hdr_plus_1_pg;
1099 uint8_t *pBuf,
int bufLen)
1103 uint8_t
cdb[10] = {};
1110 cdb[2] = (pc << 6) | (pagenum & 0x3f);
1111 cdb[3] = subpagenum;
1128 else if (pagenum != (pBuf[offset] & 0x3f))
1146 uint8_t
cdb[10] = {};
1148 int pg_offset, pg_len, hdr_plus_1_pg;
1151 if (pg_offset + 2 >= bufLen)
1153 pg_len = pBuf[pg_offset + 1] + 2;
1154 hdr_plus_1_pg = pg_offset + pg_len;
1155 if (hdr_plus_1_pg > bufLen)
1159 pBuf[pg_offset] &= 0x7f;
1164 cdb[1] = 0x10 | (sp & 1);
1187 uint8_t
cdb[6] = {};
1190 if ((bufLen < 0) || (bufLen > 1023))
1193 memset(pBuf, 0, 36);
1209 if (((bufLen - io_hdr.
resid) >= 36) &&
1211 ((pBuf[3] & 0xf) == 2)) {
1212 uint8_t pdt = pBuf[0] & 0x1f;
1233 uint8_t
cdb[6] = {};
1243 if ((bufLen < 0) || (bufLen > 1023))
1275 if (vpd_page == pBuf[1]) {
1276 if ((0x80 == vpd_page) && (bufLen > 2) && (0x0 != pBuf[2]))
1290 uint8_t
cdb[6] = {};
1292 uint8_t buff[18] = {};
1294 static const int sz_buff =
sizeof(buff);
1316 uint8_t resp_code = buff[0] & 0x7f;
1319 sense_info->
asc = 0;
1320 sense_info->
ascq = 0;
1321 if ((0x70 == resp_code) || (0x71 == resp_code)) {
1322 int len = buff[7] + 8;
1324 sense_info->
asc = buff[12];
1325 sense_info->
ascq = buff[13];
1330 switch (resp_code) {
1331 const unsigned char * ucp;
1335 sk = (buff[2] & 0xf);
1339 if (buff[15] & 0x80) {
1348 sk = (buff[1] & 0xf);
1351 (0x6 == ucp[1]) && (0x80 & ucp[4])) {
1355 ((0x6 == ucp[1]))) {
1384 uint8_t
cdb[6] = {};
1390 if (power_cond > 0) {
1391 cdb[3] = pcond_modifier & 0xf;
1392 cdb[4] = power_cond << 4;
1416 uint8_t
cdb[6] = {};
1426 cdb[1] = (functioncode & 0x7) << 5;
1448 uint8_t
cdb[6] = {};
1492 int dl_format, uint8_t *pBuf,
int bufLen)
1496 uint8_t
cdb[10] = {};
1503 cdb[2] = (
unsigned char)(((req_plist << 4) & 0x10) |
1504 ((req_glist << 3) & 0x8) | (dl_format & 0x7));
1526 int dl_format,
int addrDescIndex, uint8_t *pBuf,
int bufLen)
1530 uint8_t
cdb[12] = {};
1537 cdb[1] = (
unsigned char)(((req_plist << 4) & 0x10) |
1538 ((req_glist << 3) & 0x8) | (dl_format & 0x7));
1570 const char * ddir =
"none";
1575 ddir = dout ?
"out" :
"in";
1578 pout(
" [%s: ", np ? np :
"<unknown opcode>");
1579 pout(
"SCSI opcode=0x%x, CDB length=%u, data length=0x%u, data "
1591 unsigned int act_len;
1594 (iop->
resid >= 0) && (req_len >= (
unsigned int)iop->
resid)) {
1595 act_len = req_len - (
unsigned int)iop->
resid;
1596 pout(
" [data-in buffer: req_len=%u, resid=%d, gives %u "
1597 "bytes]\n", req_len, iop->
resid, act_len);
1615 pout(
"%s Unit Attention %d: asc/ascq=0x%x,0x%x, retrying\n",
1616 __func__, k + 1, sinfo.
asc, sinfo.
ascq);
1629 unsigned int * lb_sizep)
1634 uint8_t
cdb[10] = {};
1636 uint8_t resp[8] = {};
1668 uint8_t
cdb[16] = {};
1692 uint16_t serv_act, uint8_t *pBuf,
int bufLen,
int & rspLen)
1697 uint8_t
cdb[12] = {};
1708 cdb[2] |= (0x7 & rep_opt);
1722 rspLen = bufLen - io_hdr.
resid;
1735 bool try_16 =
false;
1736 bool try_12 =
false;
1737 unsigned int last_lba = 0, lb_size = 0;
1739 uint64_t ret_val = 0;
1740 uint8_t rc16resp[32];
1746 pout(
"%s: READ CAPACITY(10) failed, res=%d\n", __func__, res);
1749 if (0xffffffff == last_lba) {
1754 ret_val = last_lba + 1;
1756 memset(srrp, 0,
sizeof(*srrp));
1767 if (try_16 || (! avoid_rcap16)) {
1771 pout(
"%s: READ CAPACITY(16) failed, res=%d\n", __func__, res);
1781 bool prot_en = !!(0x1 & rc16resp[12]);
1782 uint8_t p_type = ((rc16resp[12] >> 1) & 0x7);
1783 srrp->
prot_type = prot_en ? (1 + p_type) : 0;
1784 srrp->
p_i_exp = ((rc16resp[13] >> 4) & 0xf);
1786 srrp->
lbpme = !!(0x80 & rc16resp[14]);
1787 srrp->
lbprz = !!(0x40 & rc16resp[14]);
1796 pout(
"%s: 2nd READ CAPACITY(10) failed, res=%d\n", __func__,
1800 ret_val = (uint64_t)last_lba + 1;
1802 memset(srrp, 0,
sizeof(*srrp));
1808 return (ret_val * lb_size);
1819 int resp_len, bd_len;
1823 offset = bd_len + 8;
1825 resp_len = resp[0] + 1;
1827 offset = bd_len + 4;
1829 if ((offset + 2) >= len) {
1830 pout(
"scsiModePageOffset: raw_curr too small, offset=%d "
1831 "resp_len=%d bd_len=%d\n", offset, resp_len, bd_len);
1833 }
else if ((offset + 2) >= resp_len) {
1835 pout(
"scsiModePageOffset: response length too short, "
1836 "resp_len=%d offset=%d bd_len=%d\n", resp_len,
1845#define DEXCPT_ENABLE 0x08
1846#define EWASC_ENABLE 0x10
1847#define DEXCPT_DISABLE 0xf7
1848#define EWASC_DISABLE 0xef
1849#define TEST_DISABLE 0xfb
1862 memset(iecp, 0,
sizeof(*iecp));
1932#define SCSI_IEC_MP_BYTE2_ENABLED 0x10
1933#define SCSI_IEC_MP_BYTE2_TEST_MASK 0x4
1935#define SCSI_IEC_MP_MRIE 6
1936#define SCSI_IEC_MP_INTERVAL_T 0
1937#define SCSI_IEC_MP_REPORT_COUNT 1
1950 int offset, resp_len;
1966 resp_len = rout[0] + 1;
1969 int sp = !! (rout[offset] & 0x80);
1980 uint8_t chg2 = iecp->
raw_chg[offset + 2];
1982 rout[offset + 2] = chg2 ? (rout[offset + 2] & chg2) :
1984 for (
int k = 3; k < 12; ++k) {
1985 if (0 == iecp->
raw_chg[offset + k])
1986 rout[offset + k] = iecp->
raw_curr[offset + k];
1989 if (0 == memcmp(&rout[offset + 2], &iecp->
raw_chg[offset + 2], 10)) {
1991 pout(
"scsiSetExceptionControlAndWarning: already enabled\n");
1996 int wEnabled = (rout[offset + 2] &
EWASC_ENABLE) ? 1 : 0;
1997 if ((! eCEnabled) && (! wEnabled)) {
1999 pout(
"scsiSetExceptionControlAndWarning: already disabled\n");
2021 uint8_t tBuf[252] = {};
2025 sizeof(tBuf), 0))) {
2032 *currenttemp = tBuf[9];
2033 *triptemp = tBuf[15];
2048 uint8_t *
asc, uint8_t *
ascq, uint8_t *currenttemp,
2051 uint8_t tBuf[252] = {};
2054 uint8_t currTemp, trTemp;
2056 memset(&sense_info, 0,
sizeof(sense_info));
2063 sizeof(tBuf), 0))) {
2069 if ((pagesize < 4) || tBuf[4] || tBuf[5]) {
2070 pout(
"%s failed, IE page, bad parameter code or length\n",
2075 sense_info.
asc = tBuf[8];
2076 sense_info.
ascq = tBuf[9];
2077 if (! hasTempLogPage) {
2079 *currenttemp = tBuf[10];
2081 *triptemp = tBuf[11];
2085 if (0 == sense_info.
asc) {
2094 if (hasTempLogPage) {
2095 if (0 ==
scsiGetTemp(device, &currTemp, &trTemp)) {
2096 *currenttemp = currTemp;
2107 "W: The tape drive is having problems reading data. No data has been "
2109 " but there has been a reduction in the performance of the tape.",
2111 "W: The tape drive is having problems writing data. No data has been "
2113 " but there has been a reduction in the capacity of the tape.",
2115 "W: The operation has stopped because an error has occurred while "
2117 " or writing data that the drive cannot correct.",
2119 "C: Your data is at risk:\n"
2120 " 1. Copy any data you require from this tape. \n"
2121 " 2. Do not use this tape again.\n"
2122 " 3. Restart the operation with a different tape.",
2124 "C: The tape is damaged or the drive is faulty. Call the tape drive\n"
2125 " supplier helpline.",
2127 "C: The tape is from a faulty batch or the tape drive is faulty:\n"
2128 " 1. Use a good tape to test the drive.\n"
2129 " 2. If problem persists, call the tape drive supplier helpline.",
2131 "W: The tape cartridge has reached the end of its calculated useful "
2133 " 1. Copy data you need to another tape.\n"
2134 " 2. Discard the old tape.",
2136 "W: The tape cartridge is not data-grade. Any data you back up to the "
2138 " is at risk. Replace the cartridge with a data-grade tape.",
2140 "C: You are trying to write to a write-protected cartridge. Remove the\n"
2141 " write-protection or use another tape.",
2143 "I: You cannot eject the cartridge because the tape drive is in use. "
2145 " until the operation is complete before ejecting the cartridge.",
2147 "I: The tape in the drive is a cleaning cartridge.",
2149 "I: You have tried to load a cartridge of a type which is not supported\n"
2152 "C: The operation has failed because the tape in the drive has "
2154 " a mechanical failure:\n"
2155 " 1. Discard the old tape.\n"
2156 " 2. Restart the operation with a different tape.",
2158 "C: The operation has failed because the tape in the drive has "
2160 " a mechanical failure:\n"
2161 " 1. Do not attempt to extract the tape cartridge\n"
2162 " 2. Call the tape drive supplier helpline.",
2164 "W: The memory in the tape cartridge has failed, which reduces\n"
2165 " performance. Do not use the cartridge for further write "
2168 "C: The operation has failed because the tape cartridge was manually\n"
2169 " de-mounted while the tape drive was actively writing or reading.",
2171 "W: You have loaded a cartridge of a type that is read-only in this "
2173 " The cartridge will appear as write-protected.",
2175 "W: The tape directory on the tape cartridge has been corrupted. File\n"
2176 " search performance will be degraded. The tape directory can be "
2178 " by reading all the data on the cartridge.",
2180 "I: The tape cartridge is nearing the end of its calculated life. It is\n"
2181 " recommended that you:\n"
2182 " 1. Use another tape cartridge for your next backup.\n"
2183 " 2. Store this tape in a safe place in case you need to restore "
2186 "C: The tape drive needs cleaning:\n"
2187 " 1. If the operation has stopped, eject the tape and clean the "
2189 " 2. If the operation has not stopped, wait for it to finish and "
2191 " clean the drive.\n"
2192 " Check the tape drive users manual for device specific cleaning "
2195 "W: The tape drive is due for routine cleaning:\n"
2196 " 1. Wait for the current operation to finish.\n"
2197 " 2. The use a cleaning cartridge.\n"
2198 " Check the tape drive users manual for device specific cleaning "
2201 "C: The last cleaning cartridge used in the tape drive has worn out:\n"
2202 " 1. Discard the worn out cleaning cartridge.\n"
2203 " 2. Wait for the current operation to finish.\n"
2204 " 3. Then use a new cleaning cartridge.",
2206 "C: The last cleaning cartridge used in the tape drive was an invalid\n"
2208 " 1. Do not use this cleaning cartridge in this drive.\n"
2209 " 2. Wait for the current operation to finish.\n"
2210 " 3. Then use a new cleaning cartridge.",
2212 "W: The tape drive has requested a retention operation",
2214 "W: A redundant interface port on the tape drive has failed",
2216 "W: A tape drive cooling fan has failed",
2218 "W: A redundant power supply has failed inside the tape drive enclosure.\n"
2219 " Check the enclosure users manual for instructions on replacing "
2221 " failed power supply.",
2223 "W: The tape drive power consumption is outside the specified range.",
2225 "W: Preventive maintenance of the tape drive is required. Check the tape\n"
2226 " drive users manual for device specific preventive maintenance\n"
2227 " tasks or call the tape drive supplier helpline.",
2229 "C: The tape drive has a hardware fault:\n"
2230 " 1. Eject the tape or magazine.\n"
2231 " 2. Reset the drive.\n"
2232 " 3. Restart the operation.",
2234 "C: The tape drive has a hardware fault:\n"
2235 " 1. Turn the tape drive off and then on again.\n"
2236 " 2. Restart the operation.\n"
2237 " 3. If the problem persists, call the tape drive supplier helpline.",
2239 "W: The tape drive has a problem with the application client interface:\n"
2240 " 1. Check the cables and cable connections.\n"
2241 " 2. Restart the operation.",
2243 "C: The operation has failed:\n"
2244 " 1. Eject the tape or magazine.\n"
2245 " 2. Insert the tape or magazine again.\n"
2246 " 3. Restart the operation.",
2248 "W: The firmware download has failed because you have tried to use the\n"
2249 " incorrect firmware for this tape drive. Obtain the correct\n"
2250 " firmware and try again.",
2252 "W: Environmental conditions inside the tape drive are outside the\n"
2253 " specified humidity range.",
2255 "W: Environmental conditions inside the tape drive are outside the\n"
2256 " specified temperature range.",
2258 "W: The voltage supply to the tape drive is outside the specified range.",
2260 "C: A hardware failure of the tape drive is predicted. Call the tape\n"
2261 " drive supplier helpline.",
2263 "W: The tape drive may have a hardware fault. Run extended diagnostics to\n"
2264 " verify and diagnose the problem. Check the tape drive users manual "
2266 " device specific instructions on running extended diagnostic tests.",
2268 "C: The changer mechanism is having difficulty communicating with the "
2271 " 1. Turn the autoloader off then on.\n"
2272 " 2. Restart the operation.\n"
2273 " 3. If problem persists, call the tape drive supplier helpline.",
2275 "C: A tape has been left in the autoloader by a previous hardware fault:\n"
2276 " 1. Insert an empty magazine to clear the fault.\n"
2277 " 2. If the fault does not clear, turn the autoloader off and then\n"
2279 " 3. If the problem persists, call the tape drive supplier helpline.",
2281 "W: There is a problem with the autoloader mechanism.",
2283 "C: The operation has failed because the autoloader door is open:\n"
2284 " 1. Clear any obstructions from the autoloader door.\n"
2285 " 2. Eject the magazine and then insert it again.\n"
2286 " 3. If the fault does not clear, turn the autoloader off and then\n"
2288 " 4. If the problem persists, call the tape drive supplier helpline.",
2290 "C: The autoloader has a hardware fault:\n"
2291 " 1. Turn the autoloader off and then on again.\n"
2292 " 2. Restart the operation.\n"
2293 " 3. If the problem persists, call the tape drive supplier helpline.\n"
2294 " Check the autoloader users manual for device specific instructions\n"
2295 " on turning the device power on and off.",
2297 "C: The autoloader cannot operate without the magazine,\n"
2298 " 1. Insert the magazine into the autoloader.\n"
2299 " 2. Restart the operation.",
2301 "W: A hardware failure of the changer mechanism is predicted. Call the\n"
2302 " tape drive supplier helpline.",
2310 "W: Media statistics have been lost at some time in the past",
2312 "W: The tape directory on the tape cartridge just unloaded has been\n"
2313 " corrupted. File search performance will be degraded. The tape\n"
2314 " directory can be rebuilt by reading all the data.",
2316 "C: The tape just unloaded could not write its system area successfully:\n"
2317 " 1. Copy data to another tape cartridge.\n"
2318 " 2. Discard the old cartridge.",
2320 "C: The tape system are could not be read successfully at load time:\n"
2321 " 1. Copy data to another tape cartridge.\n",
2323 "C: The start or data could not be found on the tape:\n"
2324 " 1. Check you are using the correct format tape.\n"
2325 " 2. Discard the tape or return the tape to your supplier",
2327 "C: The operation has failed because the media cannot be loaded\n"
2329 " 1. Remove the cartridge, inspect it as specified in the product\n"
2330 " manual, and retry the operation.\n"
2331 " 2. If the problem persists, call the tape drive supplier help "
2334 "C: The operation has failed because the medium cannot be unloaded:\n"
2335 " 1. Do not attempt to extract the tape cartridge.\n"
2336 " 2. Call the tape driver supplier help line.",
2338 "C: The tape drive has a problem with the automation interface:\n"
2339 " 1. Check the power to the automation system.\n"
2340 " 2. Check the cables and cable connections.\n"
2341 " 3. Call the supplier help line if problem persists.",
2343 "W: The tape drive has reset itself due to a detected firmware\n"
2344 " fault. If problem persists, call the supplier help line.",
2360 "C: The library mechanism is having difficulty communicating with the\n"
2362 " 1. Turn the library off then on.\n"
2363 " 2. Restart the operation.\n"
2364 " 3. If the problem persists, call the library supplier help line.",
2366 "W: There is a problem with the library mechanism. If problem persists,\n"
2367 " call the library supplier help line.",
2369 "C: The library has a hardware fault:\n"
2370 " 1. Reset the library.\n"
2371 " 2. Restart the operation.\n"
2372 " Check the library users manual for device specific instructions on "
2376 "C: The library has a hardware fault:\n"
2377 " 1. Turn the library off then on again.\n"
2378 " 2. Restart the operation.\n"
2379 " 3. If the problem persists, call the library supplier help line.\n"
2380 " Check the library users manual for device specific instructions on "
2382 " device power on and off.",
2384 "W: The library mechanism may have a hardware fault.\n"
2385 " Run extended diagnostics to verify and diagnose the problem. "
2386 "Check the library\n"
2387 " users manual for device specific instructions on running extended "
2391 "C: The library has a problem with the host interface:\n"
2392 " 1. Check the cables and connections.\n"
2393 " 2. Restart the operation.",
2395 "W: A hardware failure of the library is predicted. Call the library\n"
2396 " supplier help line.",
2398 "W: Preventive maintenance of the library is required.\n"
2399 " Check the library users manual for device specific preventative "
2401 " tasks, or call your library supplier help line.",
2403 "C: General environmental conditions inside the library are outside the\n"
2404 " specified humidity range.",
2406 "C: General environmental conditions inside the library are outside the\n"
2407 " specified temperature range.",
2409 "C: The voltage supply to the library is outside the specified range.\n"
2410 " There is a potential problem with the power supply or failure of\n"
2411 " a redundant power supply.",
2413 "C: A cartridge has been left inside the library by a previous hardware\n"
2415 " 1. Insert an empty magazine to clear the fault.\n"
2416 " 2. If the fault does not clear, turn the library off and then on "
2418 " 3. If the problem persists, call the library supplier help line.",
2420 "W: There is a potential problem with the drive ejecting cartridges or\n"
2421 " with the library mechanism picking a cartridge from a slot.\n"
2422 " 1. No action needs to be taken at this time.\n"
2423 " 2. If the problem persists, call the library supplier help line.",
2425 "W: There is a potential problem with the library mechanism placing a\n"
2426 " cartridge into a slot.\n"
2427 " 1. No action needs to be taken at this time.\n"
2428 " 2. If the problem persists, call the library supplier help line.",
2430 "W: There is a potential problem with the drive or the library mechanism\n"
2431 " loading cartridges, or an incompatible cartridge.",
2433 "C: The library has failed because the door is open:\n"
2434 " 1. Clear any obstructions from the library door.\n"
2435 " 2. Close the library door.\n"
2436 " 3. If the problem persists, call the library supplier help line.",
2438 "C: There is a mechanical problem with the library media import/export\n"
2441 "C: The library cannot operate without the magazine.\n"
2442 " 1. Insert the magazine into the library.\n"
2443 " 2. Restart the operation.",
2445 "W: Library security has been compromised.",
2447 "I: The library security mode has been changed.\n"
2448 " The library has either been put into secure mode, or the library "
2450 " the secure mode.\n"
2451 " This is for information purposes only. No action is required.",
2453 "I: The library has been manually turned offline and is unavailable for "
2456 "I: A drive inside the library has been taken offline.\n"
2457 " This is for information purposes only. No action is required.",
2459 "W: There is a potential problem with the bar code label or the scanner\n"
2460 " hardware in the library mechanism.\n"
2461 " 1. No action needs to be taken at this time.\n"
2462 " 2. If the problem persists, call the library supplier help line.",
2464 "C: The library has detected an inconsistency in its inventory.\n"
2465 " 1. Redo the library inventory to correct inconsistency.\n"
2466 " 2. Restart the operation.\n"
2467 " Check the applications users manual or the hardware users manual "
2469 " specific instructions on redoing the library inventory.",
2471 "W: A library operation has been attempted that is invalid at this time.",
2473 "W: A redundant interface port on the library has failed.",
2475 "W: A library cooling fan has failed.",
2477 "W: A redundant power supply has failed inside the library. Check the\n"
2478 " library users manual for instructions on replacing the failed "
2481 "W: The library power consumption is outside the specified range.",
2483 "C: A failure has occurred in the cartridge pass-through mechanism "
2485 " two library modules.",
2487 "C: A cartridge has been left in the pass-through mechanism from a\n"
2488 " previous hardware fault. Check the library users guide for "
2490 " clearing this fault.",
2492 "I: The library was unable to read the bar code on a cartridge.",
2534 pout(
"Long (extended) offline self test failed [%s]\n",
2557 pout(
"Long (extended) foreground self test failed [%s]\n",
2580 uint8_t buff[64] = {};
2585 buff,
sizeof(buff)))) {
2596 buff,
sizeof(buff));
2603 if (buff[offset + 1] >= 0xa) {
2619 *durationSec = res * 60;
2631 memset(ecp, 0,
sizeof(*ecp));
2633 unsigned char * ucp = &resp[0] + 4;
2636 num = num < allocLen - 4 ? num : allocLen - 4;
2639 int pl = ucp[3] + 4;
2661 unsigned char * xp = ucp + 4;
2662 if (k > (
int)
sizeof(*ullp)) {
2663 xp += (k -
sizeof(*ullp));
2677 memset(nmep, 0,
sizeof(*nmep));
2679 unsigned char * ucp = &resp[0] + 4;
2683 num = num < allocLen - 4 ? num : allocLen - 4;
2686 int pl = ucp[3] + 4;
2743 int num, k, err, fails, fail_hour;
2763 pout(
"Self-test %s length is 0x%x not 0x190 bytes\n",
logSenStr,
2770 for (k = 0, ucp = resp + 4; k < 20; ++k, ucp += 20 ) {
2777 if ((0 == n) && (0 == ucp[4]))
2779 int res = ucp[4] & 0xf;
2780 if ((res > 2) && (res < 8)) {
2786 return (fail_hour << 8) + fails;
2811 *inProgress = (0xf == (ucp[4] & 0xf)) ? 1 : 0;
2823 uint8_t buff[64] = {};
2828 buff,
sizeof(buff)))) {
2838 buff,
sizeof(buff));
2843 if ((offset >= 0) && (buff[offset + 1] >= 0xa))
2844 return (buff[offset + 2] & 2) ? 1 : 0;
2861 uint8_t buff[64] = {};
2865 buff,
sizeof(buff))) &&
2869 *form_factorp = buff[7] & 0xf;
2871 *haw_zbcp = (buff[8] >> 4) & 0x3;
2880 buff,
sizeof(buff)))) {
2890 buff,
sizeof(buff));
2905 int err, offset, resp_len, sp;
2906 uint8_t buff[64] = {};
2907 uint8_t ch_buff[64];
2908 short set_wce = *wcep;
2909 short set_rcd = *rcdp;
2913 buff,
sizeof(buff));
2918 device->
set_err(EINVAL,
"SCSI MODE SENSE failed");
2927 buff,
sizeof(buff));
2929 device->
set_err(EINVAL,
"SCSI MODE SENSE failed");
2934 if ((offset < 0) || (buff[offset + 1] < 0xa)) {
2935 device->
set_err(EINVAL,
"Bad response");
2939 *wcep = ((buff[offset + 2] & 0x04) != 0);
2940 *rcdp = ((buff[offset + 2] & 0x01) != 0);
2942 if((*wcep == set_wce || set_wce == -1)
2943 && ((*rcdp == set_rcd) || set_rcd == -1))
2949 ch_buff,
sizeof(ch_buff));
2953 ch_buff,
sizeof(ch_buff));
2955 device->
set_err(EINVAL,
"WCE/RCD bits not changeable");
2960 if(set_wce >= 0 && *wcep != set_wce) {
2961 if (0 == (ch_buff[offset + 2] & 0x04)) {
2962 device->
set_err(EINVAL,
"WCE bit not changeable");
2966 buff[offset + 2] |= 0x04;
2968 buff[offset + 2] &= 0xfb;
2971 if(set_rcd >= 0 && *rcdp != set_rcd) {
2972 if (0 == (ch_buff[offset + 2] & 0x01)) {
2973 device->
set_err(EINVAL,
"RCD bit not changeable");
2977 buff[offset + 2] |= 0x01;
2979 buff[offset + 2] &= 0xfe;
2987 resp_len = buff[0] + 1;
2996 device->
set_err(EINVAL,
"MODE SELECT command failed");
3008 int err, offset, resp_len, sp;
3009 uint8_t buff[64] = {};
3010 uint8_t ch_buff[64];
3015 buff,
sizeof(buff)))) {
3026 buff,
sizeof(buff));
3031 if ((offset < 0) || (buff[offset + 1] < 0xa))
3036 if (enabled == (buff[offset + 2] & 2))
3042 ch_buff,
sizeof(ch_buff));
3046 ch_buff,
sizeof(ch_buff));
3049 if (0 == (ch_buff[offset + 2] & 2))
3057 resp_len = buff[0] + 1;
3060 sp = (buff[offset] & 0x80) ? 1 : 0;
3062 buff[offset + 2] |= 0x2;
3064 buff[offset + 2] &= 0xfd;
3079 uint8_t buff[64] {};
3084 buff,
sizeof(buff)))) {
3095 buff,
sizeof(buff));
3100 if ((offset >= 0) && (buff[offset + 1] > 1)) {
3101 if ((0 == (buff[offset] & 0x40)) &&
3103 return (buff[offset + 2] & 0xf);
3108const unsigned char *
3113 const unsigned char * descp;
3115 if ((
sense_len < 8) || (0 == (add_sen_len = sensep[7])))
3117 if ((sensep[0] < 0x72) || (sensep[0] > 0x73))
3119 add_sen_len = (add_sen_len < (
sense_len - 8)) ?
3122 for (
int desc_len = 0, k = 0; k < add_sen_len; k += desc_len) {
3124 int add_len = (k < (add_sen_len - 1)) ? descp[1]: -1;
3125 desc_len = add_len + 2;
3126 if (descp[0] == desc_type)
3139 n = n > 64 ? 64 : n;
3140 strncpy(tmp, (
const char *)in, n);
3146 for (i = 0; tmp[i]; i++)
3147 if (!isspace((
int)tmp[i])) {
3159 for (i = strlen(tmp)-1; i >= first && isspace((
int)tmp[i]); i--);
3162 strncpy(out, tmp+first, last-first+1);
3163 out[last-first+1] =
'\0';
3166static const char *
wn =
"Warning";
3169 "specified temperature exceeded",
3170 "enclosure degraded",
3171 "background self-test failed",
3172 "background pre-scan detected medium error",
3173 "background medium scan detected medium error",
3174 "non-volatile cache now volatile",
3175 "degraded power to non-volatile cache",
3176 "power loss expected",
3177 "device statistics notification active",
3192 "general hard drive failure",
3193 "drive error rate too high",
3194 "data error rate too high",
3195 "seek error rate too high",
3196 "too many block reassigns",
3197 "access times too high",
3198 "start unit times too high",
3199 "channel parametrics",
3200 "controller detected",
3201 "throughput performance",
3202 "seek time performance",
3203 "spin-up retry count",
3204 "drive calibration retry count",
3207static const char *
pred =
"prediction threshold exceeded";
3222 snprintf(
b, blen,
"%s",
wn);
3236 snprintf(
b, blen,
"%s - microcode security at risk",
wn);
3239 snprintf(
b, blen,
"%s - microcode digital signature validation "
3243 snprintf(
b, blen,
"%s - physical element status change",
wn);
3246 if ((
ascq >= 0xa) && (
ascq <= 0x11)) {
3247 uint8_t q =
ascq - 0xa;
3249 snprintf(
b, blen,
"%s - %s %s %s limit exceeded",
wn,
3250 (((q % 2) == 0) ?
"high" :
"low"),
3251 ((((q / 2) % 2) == 0) ?
"critical" :
"operating"),
3252 ((((q / 4) % 2) == 0) ?
"temperature" :
"humidity"));
3257 }
else if (
asc == 0x5d) {
3260 snprintf(
b, blen,
"Failure %s",
pred);
3263 snprintf(
b, blen,
"Media failure %s",
pred);
3266 snprintf(
b, blen,
"Logical unit failure %s",
pred);
3269 snprintf(
b, blen,
"spare area exhaustion failure %s",
pred);
3272 snprintf(
b, blen,
"%s %s power loss protection circuit area "
3276 snprintf(
b, blen,
"Media %s endurance limit met",
impfail);
3279 snprintf(
b, blen,
"Failure %s (false)",
pred);
3282 if ((
ascq >= 0x10) && (
ascq <= 0x6c)) {
3283 uint8_t q =
ascq - 0x10;
3284 uint8_t rem = q % 0x10;
scsi_cmd_support logsense_spc_sup
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 logsense_sup
scsi_cmd_support rsoc_sup
virtual bool scsi_pass_through(scsi_cmnd_io *iop)=0
SCSI pass through.
scsi_cmd_support rdefect10_sup
scsi_cmd_support rcap16_sup
enum scsi_cmd_support cmd_support_level(uint8_t opcode, bool sa_valid, uint16_t sa, bool for_lsense_spc=false) const
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 SCSI_IEC_MP_BYTE2_ENABLED
int scsiSetExceptionControlAndWarning(scsi_device *device, int enabled, const struct scsi_iec_mode_page *iecp)
#define RSOC_ALL_CMDS_CTDP_0
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)
#define RSOC_1_CMD_CTDP_0
#define RSOC_ALL_CMDS_CTDP_1
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 scsi_cmd_support chk_lsense_spc(scsi_device *device)
static int trimTrailingSpaces(char *b)
int scsiSmartExtendSelfTest(scsi_device *device)
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)
int scsiRSOCcmd(scsi_device *device, bool rctd, uint8_t rep_opt, uint8_t opcode, uint16_t serv_act, uint8_t *pBuf, int bufLen, int &rspLen)
#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)
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