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;
760 int have_scsi_ns = 0;
764 const unsigned char * ucp =
b + off;
766 if ((off + i_len + 4) > blen) {
767 snprintf(
s+si, slen-si,
"error: designator length");
770 int assoc = ((ucp[1] >> 4) & 0x3);
771 if (transport && assoc && (ucp[1] & 0x80) && (*transport < 0))
772 *transport = (ucp[0] >> 4) & 0xf;
775 const unsigned char * ip = ucp + 4;
776 int c_set = (ucp[0] & 0xf);
777 int desig_type = (ucp[1] & 0xf);
780 switch (desig_type) {
785 if ((8 != i_len) && (12 != i_len) && (16 != i_len)) {
786 snprintf(
s+si, slen-si,
"error: EUI-64 length");
791 si += snprintf(
s+si, slen-si,
"0x");
792 for (
int m = 0; m < i_len; ++m)
793 si += snprintf(
s+si, slen-si,
"%02x", (
unsigned int)ip[m]);
797 snprintf(
s+si, slen-si,
"error: NAA bad code_set");
800 naa = (ip[0] >> 4) & 0xff;
801 if ((naa < 2) || (naa > 6) || (4 == naa)) {
802 snprintf(
s+si, slen-si,
"error: unexpected NAA");
809 snprintf(
s+si, slen-si,
"error: NAA 2 length");
812 si += snprintf(
s+si, slen-si,
"0x");
813 for (
int m = 0; m < 8; ++m)
814 si += snprintf(
s+si, slen-si,
"%02x", (
unsigned int)ip[m]);
815 }
else if ((3 == naa ) || (5 == naa)) {
818 snprintf(
s+si, slen-si,
"error: NAA 3 or 5 length");
821 si += snprintf(
s+si, slen-si,
"0x");
822 for (
int m = 0; m < 8; ++m)
823 si += snprintf(
s+si, slen-si,
"%02x", (
unsigned int)ip[m]);
824 }
else if (6 == naa) {
826 snprintf(
s+si, slen-si,
"error: NAA 6 length");
829 si += snprintf(
s+si, slen-si,
"0x");
830 for (
int m = 0; m < 16; ++m)
831 si += snprintf(
s+si, slen-si,
"%02x", (
unsigned int)ip[m]);
841 snprintf(
s+si, slen-si,
"error: SCSI name string");
846 si += snprintf(
s+si, slen-si,
"%s", (
const char *)ip);
855 snprintf(
s+si, slen-si,
"error: bad structure");
874 int bufLen,
int known_resp_len)
879 uint8_t
cdb[10] = {};
882 if (known_resp_len > bufLen)
884 if (known_resp_len > 0)
885 pageLen = known_resp_len;
886 else if (known_resp_len < 0)
891 if (pageLen > bufLen)
894 memset(pBuf, 0, pageLen);
900 cdb[2] = 0x40 | (pagenum & 0x3f);
924 if (pageLen > bufLen)
928 memset(&io_hdr, 0,
sizeof(io_hdr));
929 memset(
cdb, 0,
sizeof(
cdb));
934 cdb[2] = 0x40 | (pagenum & 0x3f);
963 int subpagenum, uint8_t *pBuf,
int bufLen)
967 uint8_t
cdb[10] = {};
974 cdb[1] = (pcr ? 2 : 0) | (sp ? 1 : 0);
975 cdb[2] = ((pc << 6) & 0xc0) | (pagenum & 0x3f);
976 cdb[3] = (subpagenum & 0xff);
995 uint8_t *pBuf,
int bufLen)
1002 if ((bufLen < 0) || (bufLen > 255))
1008 cdb[2] = (pc << 6) | (pagenum & 0x3f);
1009 cdb[3] = subpagenum;
1026 else if (pagenum != (pBuf[offset] & 0x3f))
1044 uint8_t
cdb[6] = {};
1046 int pg_offset, pg_len, hdr_plus_1_pg;
1048 pg_offset = 4 + pBuf[3];
1049 if (pg_offset + 2 >= bufLen)
1051 pg_len = pBuf[pg_offset + 1] + 2;
1052 hdr_plus_1_pg = pg_offset + pg_len;
1053 if (hdr_plus_1_pg > bufLen)
1056 pBuf[pg_offset] &= 0x7f;
1061 cdb[1] = 0x10 | (sp & 1);
1062 cdb[4] = hdr_plus_1_pg;
1080 uint8_t *pBuf,
int bufLen)
1084 uint8_t
cdb[10] = {};
1091 cdb[2] = (pc << 6) | (pagenum & 0x3f);
1092 cdb[3] = subpagenum;
1109 else if (pagenum != (pBuf[offset] & 0x3f))
1127 uint8_t
cdb[10] = {};
1129 int pg_offset, pg_len, hdr_plus_1_pg;
1132 if (pg_offset + 2 >= bufLen)
1134 pg_len = pBuf[pg_offset + 1] + 2;
1135 hdr_plus_1_pg = pg_offset + pg_len;
1136 if (hdr_plus_1_pg > bufLen)
1140 pBuf[pg_offset] &= 0x7f;
1145 cdb[1] = 0x10 | (sp & 1);
1168 uint8_t
cdb[6] = {};
1171 if ((bufLen < 0) || (bufLen > 1023))
1174 memset(pBuf, 0, 36);
1190 if (((bufLen - io_hdr.
resid) >= 36) &&
1192 ((pBuf[3] & 0xf) == 2)) {
1193 uint8_t pdt = pBuf[0] & 0x1f;
1214 uint8_t
cdb[6] = {};
1224 if ((bufLen < 0) || (bufLen > 1023))
1256 if (vpd_page == pBuf[1]) {
1257 if ((0x80 == vpd_page) && (bufLen > 2) && (0x0 != pBuf[2]))
1271 uint8_t
cdb[6] = {};
1273 uint8_t buff[18] = {};
1275 static const int sz_buff =
sizeof(buff);
1297 uint8_t resp_code = buff[0] & 0x7f;
1300 sense_info->
asc = 0;
1301 sense_info->
ascq = 0;
1302 if ((0x70 == resp_code) || (0x71 == resp_code)) {
1303 int len = buff[7] + 8;
1305 sense_info->
asc = buff[12];
1306 sense_info->
ascq = buff[13];
1311 switch (resp_code) {
1312 const unsigned char * ucp;
1316 sk = (buff[2] & 0xf);
1320 if (buff[15] & 0x80) {
1329 sk = (buff[1] & 0xf);
1332 (0x6 == ucp[1]) && (0x80 & ucp[4])) {
1336 ((0x6 == ucp[1]))) {
1365 uint8_t
cdb[6] = {};
1371 if (power_cond > 0) {
1372 cdb[3] = pcond_modifier & 0xf;
1373 cdb[4] = power_cond << 4;
1397 uint8_t
cdb[6] = {};
1407 cdb[1] = (functioncode & 0x7) << 5;
1429 uint8_t
cdb[6] = {};
1473 int dl_format, uint8_t *pBuf,
int bufLen)
1477 uint8_t
cdb[10] = {};
1484 cdb[2] = (
unsigned char)(((req_plist << 4) & 0x10) |
1485 ((req_glist << 3) & 0x8) | (dl_format & 0x7));
1507 int dl_format,
int addrDescIndex, uint8_t *pBuf,
int bufLen)
1511 uint8_t
cdb[12] = {};
1518 cdb[1] = (
unsigned char)(((req_plist << 4) & 0x10) |
1519 ((req_glist << 3) & 0x8) | (dl_format & 0x7));
1551 const char * ddir =
"none";
1556 ddir = dout ?
"out" :
"in";
1559 pout(
" [%s: ", np ? np :
"<unknown opcode>");
1560 pout(
"SCSI opcode=0x%x, CDB length=%u, data length=0x%u, data "
1572 unsigned int act_len;
1575 (iop->
resid >= 0) && (req_len >= (
unsigned int)iop->
resid)) {
1576 act_len = req_len - (
unsigned int)iop->
resid;
1577 pout(
" [data-in buffer: req_len=%u, resid=%d, gives %u "
1578 "bytes]\n", req_len, iop->
resid, act_len);
1596 pout(
"%s Unit Attention %d: asc/ascq=0x%x,0x%x, retrying\n",
1597 __func__, k + 1, sinfo.
asc, sinfo.
ascq);
1610 unsigned int * lb_sizep)
1615 uint8_t
cdb[10] = {};
1617 uint8_t resp[8] = {};
1649 uint8_t
cdb[16] = {};
1673 uint16_t serv_act, uint8_t *pBuf,
int bufLen,
int & rspLen)
1678 uint8_t
cdb[12] = {};
1689 cdb[2] |= (0x7 & rep_opt);
1703 rspLen = bufLen - io_hdr.
resid;
1716 bool try_16 =
false;
1717 bool try_12 =
false;
1718 unsigned int last_lba = 0, lb_size = 0;
1720 uint64_t ret_val = 0;
1721 uint8_t rc16resp[32];
1727 pout(
"%s: READ CAPACITY(10) failed, res=%d\n", __func__, res);
1730 if (0xffffffff == last_lba) {
1735 ret_val = last_lba + 1;
1737 memset(srrp, 0,
sizeof(*srrp));
1748 if (try_16 || (! avoid_rcap16)) {
1752 pout(
"%s: READ CAPACITY(16) failed, res=%d\n", __func__, res);
1762 bool prot_en = !!(0x1 & rc16resp[12]);
1763 uint8_t p_type = ((rc16resp[12] >> 1) & 0x7);
1764 srrp->
prot_type = prot_en ? (1 + p_type) : 0;
1765 srrp->
p_i_exp = ((rc16resp[13] >> 4) & 0xf);
1767 srrp->
lbpme = !!(0x80 & rc16resp[14]);
1768 srrp->
lbprz = !!(0x40 & rc16resp[14]);
1777 pout(
"%s: 2nd READ CAPACITY(10) failed, res=%d\n", __func__,
1781 ret_val = (uint64_t)last_lba + 1;
1783 memset(srrp, 0,
sizeof(*srrp));
1789 return (ret_val * lb_size);
1800 int resp_len, bd_len;
1804 offset = bd_len + 8;
1806 resp_len = resp[0] + 1;
1808 offset = bd_len + 4;
1810 if ((offset + 2) >= len) {
1811 pout(
"scsiModePageOffset: raw_curr too small, offset=%d "
1812 "resp_len=%d bd_len=%d\n", offset, resp_len, bd_len);
1814 }
else if ((offset + 2) >= resp_len) {
1816 pout(
"scsiModePageOffset: response length too short, "
1817 "resp_len=%d offset=%d bd_len=%d\n", resp_len,
1826#define DEXCPT_ENABLE 0x08
1827#define EWASC_ENABLE 0x10
1828#define DEXCPT_DISABLE 0xf7
1829#define EWASC_DISABLE 0xef
1830#define TEST_DISABLE 0xfb
1843 memset(iecp, 0,
sizeof(*iecp));
1913#define SCSI_IEC_MP_BYTE2_ENABLED 0x10
1914#define SCSI_IEC_MP_BYTE2_TEST_MASK 0x4
1916#define SCSI_IEC_MP_MRIE 6
1917#define SCSI_IEC_MP_INTERVAL_T 0
1918#define SCSI_IEC_MP_REPORT_COUNT 1
1931 int offset, resp_len;
1947 resp_len = rout[0] + 1;
1950 int sp = !! (rout[offset] & 0x80);
1961 uint8_t chg2 = iecp->
raw_chg[offset + 2];
1963 rout[offset + 2] = chg2 ? (rout[offset + 2] & chg2) :
1965 for (
int k = 3; k < 12; ++k) {
1966 if (0 == iecp->
raw_chg[offset + k])
1967 rout[offset + k] = iecp->
raw_curr[offset + k];
1970 if (0 == memcmp(&rout[offset + 2], &iecp->
raw_chg[offset + 2], 10)) {
1972 pout(
"scsiSetExceptionControlAndWarning: already enabled\n");
1977 int wEnabled = (rout[offset + 2] &
EWASC_ENABLE) ? 1 : 0;
1978 if ((! eCEnabled) && (! wEnabled)) {
1980 pout(
"scsiSetExceptionControlAndWarning: already disabled\n");
2002 uint8_t tBuf[252] = {};
2006 sizeof(tBuf), 0))) {
2013 *currenttemp = tBuf[9];
2014 *triptemp = tBuf[15];
2029 uint8_t *
asc, uint8_t *
ascq, uint8_t *currenttemp,
2032 uint8_t tBuf[252] = {};
2035 uint8_t currTemp, trTemp;
2037 memset(&sense_info, 0,
sizeof(sense_info));
2044 sizeof(tBuf), 0))) {
2050 if ((pagesize < 4) || tBuf[4] || tBuf[5]) {
2051 pout(
"%s failed, IE page, bad parameter code or length\n",
2056 sense_info.
asc = tBuf[8];
2057 sense_info.
ascq = tBuf[9];
2058 if (! hasTempLogPage) {
2060 *currenttemp = tBuf[10];
2062 *triptemp = tBuf[11];
2066 if (0 == sense_info.
asc) {
2075 if (hasTempLogPage) {
2076 if (0 ==
scsiGetTemp(device, &currTemp, &trTemp)) {
2077 *currenttemp = currTemp;
2088 "W: The tape drive is having problems reading data. No data has been "
2090 " but there has been a reduction in the performance of the tape.",
2092 "W: The tape drive is having problems writing data. No data has been "
2094 " but there has been a reduction in the capacity of the tape.",
2096 "W: The operation has stopped because an error has occurred while "
2098 " or writing data that the drive cannot correct.",
2100 "C: Your data is at risk:\n"
2101 " 1. Copy any data you require from this tape. \n"
2102 " 2. Do not use this tape again.\n"
2103 " 3. Restart the operation with a different tape.",
2105 "C: The tape is damaged or the drive is faulty. Call the tape drive\n"
2106 " supplier helpline.",
2108 "C: The tape is from a faulty batch or the tape drive is faulty:\n"
2109 " 1. Use a good tape to test the drive.\n"
2110 " 2. If problem persists, call the tape drive supplier helpline.",
2112 "W: The tape cartridge has reached the end of its calculated useful "
2114 " 1. Copy data you need to another tape.\n"
2115 " 2. Discard the old tape.",
2117 "W: The tape cartridge is not data-grade. Any data you back up to the "
2119 " is at risk. Replace the cartridge with a data-grade tape.",
2121 "C: You are trying to write to a write-protected cartridge. Remove the\n"
2122 " write-protection or use another tape.",
2124 "I: You cannot eject the cartridge because the tape drive is in use. "
2126 " until the operation is complete before ejecting the cartridge.",
2128 "I: The tape in the drive is a cleaning cartridge.",
2130 "I: You have tried to load a cartridge of a type which is not supported\n"
2133 "C: The operation has failed because the tape in the drive has "
2135 " a mechanical failure:\n"
2136 " 1. Discard the old tape.\n"
2137 " 2. Restart the operation with a different tape.",
2139 "C: The operation has failed because the tape in the drive has "
2141 " a mechanical failure:\n"
2142 " 1. Do not attempt to extract the tape cartridge\n"
2143 " 2. Call the tape drive supplier helpline.",
2145 "W: The memory in the tape cartridge has failed, which reduces\n"
2146 " performance. Do not use the cartridge for further write "
2149 "C: The operation has failed because the tape cartridge was manually\n"
2150 " de-mounted while the tape drive was actively writing or reading.",
2152 "W: You have loaded a cartridge of a type that is read-only in this "
2154 " The cartridge will appear as write-protected.",
2156 "W: The tape directory on the tape cartridge has been corrupted. File\n"
2157 " search performance will be degraded. The tape directory can be "
2159 " by reading all the data on the cartridge.",
2161 "I: The tape cartridge is nearing the end of its calculated life. It is\n"
2162 " recommended that you:\n"
2163 " 1. Use another tape cartridge for your next backup.\n"
2164 " 2. Store this tape in a safe place in case you need to restore "
2167 "C: The tape drive needs cleaning:\n"
2168 " 1. If the operation has stopped, eject the tape and clean the "
2170 " 2. If the operation has not stopped, wait for it to finish and "
2172 " clean the drive.\n"
2173 " Check the tape drive users manual for device specific cleaning "
2176 "W: The tape drive is due for routine cleaning:\n"
2177 " 1. Wait for the current operation to finish.\n"
2178 " 2. The use a cleaning cartridge.\n"
2179 " Check the tape drive users manual for device specific cleaning "
2182 "C: The last cleaning cartridge used in the tape drive has worn out:\n"
2183 " 1. Discard the worn out cleaning cartridge.\n"
2184 " 2. Wait for the current operation to finish.\n"
2185 " 3. Then use a new cleaning cartridge.",
2187 "C: The last cleaning cartridge used in the tape drive was an invalid\n"
2189 " 1. Do not use this cleaning cartridge in this drive.\n"
2190 " 2. Wait for the current operation to finish.\n"
2191 " 3. Then use a new cleaning cartridge.",
2193 "W: The tape drive has requested a retention operation",
2195 "W: A redundant interface port on the tape drive has failed",
2197 "W: A tape drive cooling fan has failed",
2199 "W: A redundant power supply has failed inside the tape drive enclosure.\n"
2200 " Check the enclosure users manual for instructions on replacing "
2202 " failed power supply.",
2204 "W: The tape drive power consumption is outside the specified range.",
2206 "W: Preventive maintenance of the tape drive is required. Check the tape\n"
2207 " drive users manual for device specific preventive maintenance\n"
2208 " tasks or call the tape drive supplier helpline.",
2210 "C: The tape drive has a hardware fault:\n"
2211 " 1. Eject the tape or magazine.\n"
2212 " 2. Reset the drive.\n"
2213 " 3. Restart the operation.",
2215 "C: The tape drive has a hardware fault:\n"
2216 " 1. Turn the tape drive off and then on again.\n"
2217 " 2. Restart the operation.\n"
2218 " 3. If the problem persists, call the tape drive supplier helpline.",
2220 "W: The tape drive has a problem with the application client interface:\n"
2221 " 1. Check the cables and cable connections.\n"
2222 " 2. Restart the operation.",
2224 "C: The operation has failed:\n"
2225 " 1. Eject the tape or magazine.\n"
2226 " 2. Insert the tape or magazine again.\n"
2227 " 3. Restart the operation.",
2229 "W: The firmware download has failed because you have tried to use the\n"
2230 " incorrect firmware for this tape drive. Obtain the correct\n"
2231 " firmware and try again.",
2233 "W: Environmental conditions inside the tape drive are outside the\n"
2234 " specified humidity range.",
2236 "W: Environmental conditions inside the tape drive are outside the\n"
2237 " specified temperature range.",
2239 "W: The voltage supply to the tape drive is outside the specified range.",
2241 "C: A hardware failure of the tape drive is predicted. Call the tape\n"
2242 " drive supplier helpline.",
2244 "W: The tape drive may have a hardware fault. Run extended diagnostics to\n"
2245 " verify and diagnose the problem. Check the tape drive users manual "
2247 " device specific instructions on running extended diagnostic tests.",
2249 "C: The changer mechanism is having difficulty communicating with the "
2252 " 1. Turn the autoloader off then on.\n"
2253 " 2. Restart the operation.\n"
2254 " 3. If problem persists, call the tape drive supplier helpline.",
2256 "C: A tape has been left in the autoloader by a previous hardware fault:\n"
2257 " 1. Insert an empty magazine to clear the fault.\n"
2258 " 2. If the fault does not clear, turn the autoloader off and then\n"
2260 " 3. If the problem persists, call the tape drive supplier helpline.",
2262 "W: There is a problem with the autoloader mechanism.",
2264 "C: The operation has failed because the autoloader door is open:\n"
2265 " 1. Clear any obstructions from the autoloader door.\n"
2266 " 2. Eject the magazine and then insert it again.\n"
2267 " 3. If the fault does not clear, turn the autoloader off and then\n"
2269 " 4. If the problem persists, call the tape drive supplier helpline.",
2271 "C: The autoloader has a hardware fault:\n"
2272 " 1. Turn the autoloader off and then on again.\n"
2273 " 2. Restart the operation.\n"
2274 " 3. If the problem persists, call the tape drive supplier helpline.\n"
2275 " Check the autoloader users manual for device specific instructions\n"
2276 " on turning the device power on and off.",
2278 "C: The autoloader cannot operate without the magazine,\n"
2279 " 1. Insert the magazine into the autoloader.\n"
2280 " 2. Restart the operation.",
2282 "W: A hardware failure of the changer mechanism is predicted. Call the\n"
2283 " tape drive supplier helpline.",
2291 "W: Media statistics have been lost at some time in the past",
2293 "W: The tape directory on the tape cartridge just unloaded has been\n"
2294 " corrupted. File search performance will be degraded. The tape\n"
2295 " directory can be rebuilt by reading all the data.",
2297 "C: The tape just unloaded could not write its system area successfully:\n"
2298 " 1. Copy data to another tape cartridge.\n"
2299 " 2. Discard the old cartridge.",
2301 "C: The tape system are could not be read successfully at load time:\n"
2302 " 1. Copy data to another tape cartridge.\n",
2304 "C: The start or data could not be found on the tape:\n"
2305 " 1. Check you are using the correct format tape.\n"
2306 " 2. Discard the tape or return the tape to your supplier",
2308 "C: The operation has failed because the media cannot be loaded\n"
2310 " 1. Remove the cartridge, inspect it as specified in the product\n"
2311 " manual, and retry the operation.\n"
2312 " 2. If the problem persists, call the tape drive supplier help "
2315 "C: The operation has failed because the medium cannot be unloaded:\n"
2316 " 1. Do not attempt to extract the tape cartridge.\n"
2317 " 2. Call the tape driver supplier help line.",
2319 "C: The tape drive has a problem with the automation interface:\n"
2320 " 1. Check the power to the automation system.\n"
2321 " 2. Check the cables and cable connections.\n"
2322 " 3. Call the supplier help line if problem persists.",
2324 "W: The tape drive has reset itself due to a detected firmware\n"
2325 " fault. If problem persists, call the supplier help line.",
2341 "C: The library mechanism is having difficulty communicating with the\n"
2343 " 1. Turn the library off then on.\n"
2344 " 2. Restart the operation.\n"
2345 " 3. If the problem persists, call the library supplier help line.",
2347 "W: There is a problem with the library mechanism. If problem persists,\n"
2348 " call the library supplier help line.",
2350 "C: The library has a hardware fault:\n"
2351 " 1. Reset the library.\n"
2352 " 2. Restart the operation.\n"
2353 " Check the library users manual for device specific instructions on "
2357 "C: The library has a hardware fault:\n"
2358 " 1. Turn the library off then on again.\n"
2359 " 2. Restart the operation.\n"
2360 " 3. If the problem persists, call the library supplier help line.\n"
2361 " Check the library users manual for device specific instructions on "
2363 " device power on and off.",
2365 "W: The library mechanism may have a hardware fault.\n"
2366 " Run extended diagnostics to verify and diagnose the problem. "
2367 "Check the library\n"
2368 " users manual for device specific instructions on running extended "
2372 "C: The library has a problem with the host interface:\n"
2373 " 1. Check the cables and connections.\n"
2374 " 2. Restart the operation.",
2376 "W: A hardware failure of the library is predicted. Call the library\n"
2377 " supplier help line.",
2379 "W: Preventive maintenance of the library is required.\n"
2380 " Check the library users manual for device specific preventative "
2382 " tasks, or call your library supplier help line.",
2384 "C: General environmental conditions inside the library are outside the\n"
2385 " specified humidity range.",
2387 "C: General environmental conditions inside the library are outside the\n"
2388 " specified temperature range.",
2390 "C: The voltage supply to the library is outside the specified range.\n"
2391 " There is a potential problem with the power supply or failure of\n"
2392 " a redundant power supply.",
2394 "C: A cartridge has been left inside the library by a previous hardware\n"
2396 " 1. Insert an empty magazine to clear the fault.\n"
2397 " 2. If the fault does not clear, turn the library off and then on "
2399 " 3. If the problem persists, call the library supplier help line.",
2401 "W: There is a potential problem with the drive ejecting cartridges or\n"
2402 " with the library mechanism picking a cartridge from a slot.\n"
2403 " 1. No action needs to be taken at this time.\n"
2404 " 2. If the problem persists, call the library supplier help line.",
2406 "W: There is a potential problem with the library mechanism placing a\n"
2407 " cartridge into a slot.\n"
2408 " 1. No action needs to be taken at this time.\n"
2409 " 2. If the problem persists, call the library supplier help line.",
2411 "W: There is a potential problem with the drive or the library mechanism\n"
2412 " loading cartridges, or an incompatible cartridge.",
2414 "C: The library has failed because the door is open:\n"
2415 " 1. Clear any obstructions from the library door.\n"
2416 " 2. Close the library door.\n"
2417 " 3. If the problem persists, call the library supplier help line.",
2419 "C: There is a mechanical problem with the library media import/export\n"
2422 "C: The library cannot operate without the magazine.\n"
2423 " 1. Insert the magazine into the library.\n"
2424 " 2. Restart the operation.",
2426 "W: Library security has been compromised.",
2428 "I: The library security mode has been changed.\n"
2429 " The library has either been put into secure mode, or the library "
2431 " the secure mode.\n"
2432 " This is for information purposes only. No action is required.",
2434 "I: The library has been manually turned offline and is unavailable for "
2437 "I: A drive inside the library has been taken offline.\n"
2438 " This is for information purposes only. No action is required.",
2440 "W: There is a potential problem with the bar code label or the scanner\n"
2441 " hardware in the library mechanism.\n"
2442 " 1. No action needs to be taken at this time.\n"
2443 " 2. If the problem persists, call the library supplier help line.",
2445 "C: The library has detected an inconsistency in its inventory.\n"
2446 " 1. Redo the library inventory to correct inconsistency.\n"
2447 " 2. Restart the operation.\n"
2448 " Check the applications users manual or the hardware users manual "
2450 " specific instructions on redoing the library inventory.",
2452 "W: A library operation has been attempted that is invalid at this time.",
2454 "W: A redundant interface port on the library has failed.",
2456 "W: A library cooling fan has failed.",
2458 "W: A redundant power supply has failed inside the library. Check the\n"
2459 " library users manual for instructions on replacing the failed "
2462 "W: The library power consumption is outside the specified range.",
2464 "C: A failure has occurred in the cartridge pass-through mechanism "
2466 " two library modules.",
2468 "C: A cartridge has been left in the pass-through mechanism from a\n"
2469 " previous hardware fault. Check the library users guide for "
2471 " clearing this fault.",
2473 "I: The library was unable to read the bar code on a cartridge.",
2515 pout(
"Long (extended) offline self test failed [%s]\n",
2538 pout(
"Long (extended) foreground self test failed [%s]\n",
2561 uint8_t buff[64] = {};
2566 buff,
sizeof(buff)))) {
2577 buff,
sizeof(buff));
2584 if (buff[offset + 1] >= 0xa) {
2600 *durationSec = res * 60;
2612 memset(ecp, 0,
sizeof(*ecp));
2614 unsigned char * ucp = &resp[0] + 4;
2617 num = num < allocLen - 4 ? num : allocLen - 4;
2620 int pl = ucp[3] + 4;
2642 unsigned char * xp = ucp + 4;
2643 if (k > (
int)
sizeof(*ullp)) {
2644 xp += (k -
sizeof(*ullp));
2658 memset(nmep, 0,
sizeof(*nmep));
2660 unsigned char * ucp = &resp[0] + 4;
2664 num = num < allocLen - 4 ? num : allocLen - 4;
2667 int pl = ucp[3] + 4;
2724 int num, k, err, fails, fail_hour;
2744 pout(
"Self-test %s length is 0x%x not 0x190 bytes\n",
logSenStr,
2751 for (k = 0, ucp = resp + 4; k < 20; ++k, ucp += 20 ) {
2758 if ((0 == n) && (0 == ucp[4]))
2760 int res = ucp[4] & 0xf;
2761 if ((res > 2) && (res < 8)) {
2767 return (fail_hour << 8) + fails;
2792 *inProgress = (0xf == (ucp[4] & 0xf)) ? 1 : 0;
2804 uint8_t buff[64] = {};
2809 buff,
sizeof(buff)))) {
2819 buff,
sizeof(buff));
2824 if ((offset >= 0) && (buff[offset + 1] >= 0xa))
2825 return (buff[offset + 2] & 2) ? 1 : 0;
2842 uint8_t buff[64] = {};
2846 buff,
sizeof(buff))) &&
2850 *form_factorp = buff[7] & 0xf;
2852 *haw_zbcp = (buff[8] >> 4) & 0x3;
2861 buff,
sizeof(buff)))) {
2871 buff,
sizeof(buff));
2886 int err, offset, resp_len, sp;
2887 uint8_t buff[64] = {};
2888 uint8_t ch_buff[64];
2889 short set_wce = *wcep;
2890 short set_rcd = *rcdp;
2894 buff,
sizeof(buff));
2899 device->
set_err(EINVAL,
"SCSI MODE SENSE failed");
2908 buff,
sizeof(buff));
2910 device->
set_err(EINVAL,
"SCSI MODE SENSE failed");
2915 if ((offset < 0) || (buff[offset + 1] < 0xa)) {
2916 device->
set_err(EINVAL,
"Bad response");
2920 *wcep = ((buff[offset + 2] & 0x04) != 0);
2921 *rcdp = ((buff[offset + 2] & 0x01) != 0);
2923 if((*wcep == set_wce || set_wce == -1)
2924 && ((*rcdp == set_rcd) || set_rcd == -1))
2930 ch_buff,
sizeof(ch_buff));
2934 ch_buff,
sizeof(ch_buff));
2936 device->
set_err(EINVAL,
"WCE/RCD bits not changeable");
2941 if(set_wce >= 0 && *wcep != set_wce) {
2942 if (0 == (ch_buff[offset + 2] & 0x04)) {
2943 device->
set_err(EINVAL,
"WCE bit not changeable");
2947 buff[offset + 2] |= 0x04;
2949 buff[offset + 2] &= 0xfb;
2952 if(set_rcd >= 0 && *rcdp != set_rcd) {
2953 if (0 == (ch_buff[offset + 2] & 0x01)) {
2954 device->
set_err(EINVAL,
"RCD bit not changeable");
2958 buff[offset + 2] |= 0x01;
2960 buff[offset + 2] &= 0xfe;
2968 resp_len = buff[0] + 1;
2977 device->
set_err(EINVAL,
"MODE SELECT command failed");
2989 int err, offset, resp_len, sp;
2990 uint8_t buff[64] = {};
2991 uint8_t ch_buff[64];
2996 buff,
sizeof(buff)))) {
3007 buff,
sizeof(buff));
3012 if ((offset < 0) || (buff[offset + 1] < 0xa))
3017 if (enabled == (buff[offset + 2] & 2))
3023 ch_buff,
sizeof(ch_buff));
3027 ch_buff,
sizeof(ch_buff));
3030 if (0 == (ch_buff[offset + 2] & 2))
3038 resp_len = buff[0] + 1;
3041 sp = (buff[offset] & 0x80) ? 1 : 0;
3043 buff[offset + 2] |= 0x2;
3045 buff[offset + 2] &= 0xfd;
3060 uint8_t buff[64] {};
3065 buff,
sizeof(buff)))) {
3076 buff,
sizeof(buff));
3081 if ((offset >= 0) && (buff[offset + 1] > 1)) {
3082 if ((0 == (buff[offset] & 0x40)) &&
3084 return (buff[offset + 2] & 0xf);
3089const unsigned char *
3094 const unsigned char * descp;
3096 if ((
sense_len < 8) || (0 == (add_sen_len = sensep[7])))
3098 if ((sensep[0] < 0x72) || (sensep[0] > 0x73))
3100 add_sen_len = (add_sen_len < (
sense_len - 8)) ?
3103 for (
int desc_len = 0, k = 0; k < add_sen_len; k += desc_len) {
3105 int add_len = (k < (add_sen_len - 1)) ? descp[1]: -1;
3106 desc_len = add_len + 2;
3107 if (descp[0] == desc_type)
3120 n = n > 64 ? 64 : n;
3121 strncpy(tmp, (
const char *)in, n);
3127 for (i = 0; tmp[i]; i++)
3128 if (!isspace((
int)tmp[i])) {
3140 for (i = strlen(tmp)-1; i >= first && isspace((
int)tmp[i]); i--);
3143 strncpy(out, tmp+first, last-first+1);
3144 out[last-first+1] =
'\0';
3147static const char *
wn =
"Warning";
3150 "specified temperature exceeded",
3151 "enclosure degraded",
3152 "background self-test failed",
3153 "background pre-scan detected medium error",
3154 "background medium scan detected medium error",
3155 "non-volatile cache now volatile",
3156 "degraded power to non-volatile cache",
3157 "power loss expected",
3158 "device statistics notification active",
3173 "general hard drive failure",
3174 "drive error rate too high",
3175 "data error rate too high",
3176 "seek error rate too high",
3177 "too many block reassigns",
3178 "access times too high",
3179 "start unit times too high",
3180 "channel parametrics",
3181 "controller detected",
3182 "throughput performance",
3183 "seek time performance",
3184 "spin-up retry count",
3185 "drive calibration retry count",
3188static const char *
pred =
"prediction threshold exceeded";
3203 snprintf(
b, blen,
"%s",
wn);
3217 snprintf(
b, blen,
"%s - microcode security at risk",
wn);
3220 snprintf(
b, blen,
"%s - microcode digital signature validation "
3224 snprintf(
b, blen,
"%s - physical element status change",
wn);
3227 if ((
ascq >= 0xa) && (
ascq <= 0x11)) {
3228 uint8_t q =
ascq - 0xa;
3230 snprintf(
b, blen,
"%s - %s %s %s limit exceeded",
wn,
3231 (((q % 2) == 0) ?
"high" :
"low"),
3232 ((((q / 2) % 2) == 0) ?
"critical" :
"operating"),
3233 ((((q / 4) % 2) == 0) ?
"temperature" :
"humidity"));
3238 }
else if (
asc == 0x5d) {
3241 snprintf(
b, blen,
"Failure %s",
pred);
3244 snprintf(
b, blen,
"Media failure %s",
pred);
3247 snprintf(
b, blen,
"Logical unit failure %s",
pred);
3250 snprintf(
b, blen,
"spare area exhaustion failure %s",
pred);
3253 snprintf(
b, blen,
"%s %s power loss protection circuit area "
3257 snprintf(
b, blen,
"Media %s endurance limit met",
impfail);
3260 snprintf(
b, blen,
"Failure %s (false)",
pred);
3263 if ((
ascq >= 0x10) && (
ascq <= 0x6c)) {
3264 uint8_t q =
ascq - 0x10;
3265 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