"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/sg_cmds_extra.c" between
sdparm-1.11.tgz and sdparm-1.12.tgz

About: sdparm let you access SCSI modes pages, read VPD pages, send simple SCSI commands (similar functionality for SCSI disks like "hdparm" for ATA disks).

sg_cmds_extra.c  (sdparm-1.11.tgz):sg_cmds_extra.c  (sdparm-1.12.tgz)
/* /*
* Copyright (c) 1999-2019 Douglas Gilbert. * Copyright (c) 1999-2020 Douglas Gilbert.
* All rights reserved. * All rights reserved.
* Use of this source code is governed by a BSD-style * Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file. * license that can be found in the BSD_LICENSE file.
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
skipping to change at line 448 skipping to change at line 448
destruct_scsi_pt_obj(ptvp); destruct_scsi_pt_obj(ptvp);
return ret; return ret;
} }
/* Invokes a SCSI SEND DIAGNOSTIC command. Foreground, extended self tests can /* Invokes a SCSI SEND DIAGNOSTIC command. Foreground, extended self tests can
* take a long time, if so set long_duration flag in which case the timeout * take a long time, if so set long_duration flag in which case the timeout
* is set to 7200 seconds; if the value of long_duration is > 7200 then that * is set to 7200 seconds; if the value of long_duration is > 7200 then that
* value is taken as the timeout value in seconds. Return of 0 -> success, * value is taken as the timeout value in seconds. Return of 0 -> success,
* various SG_LIB_CAT_* positive values or -1 -> other errors */ * various SG_LIB_CAT_* positive values or -1 -> other errors */
int int
sg_ll_send_diag_pt(struct sg_pt_base * ptvp, int st_code, bool pf_bit, sg_ll_send_diag_com(struct sg_pt_base * ptvp, int sg_fd, int st_code,
bool st_bit, bool devofl_bit, bool unitofl_bit, bool pf_bit, bool st_bit, bool devofl_bit,
int long_duration, void * paramp, int param_len, bool unitofl_bit, int long_duration, void * paramp,
bool noisy, int vb) int param_len, bool noisy, int vb)
{ {
static const char * const cdb_s = "Send diagnostic"; static const char * const cdb_s = "Send diagnostic";
bool ptvp_given = false;
bool local_sense = true;
bool local_cdb = true;
int res, ret, s_cat, tmout; int res, ret, s_cat, tmout;
uint8_t senddiag_cdb[SEND_DIAGNOSTIC_CMDLEN] = uint8_t senddiag_cdb[SEND_DIAGNOSTIC_CMDLEN] =
{SEND_DIAGNOSTIC_CMD, 0, 0, 0, 0, 0}; {SEND_DIAGNOSTIC_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN]; uint8_t sense_b[SENSE_BUFF_LEN];
senddiag_cdb[1] = (uint8_t)(st_code << 5); senddiag_cdb[1] = (uint8_t)(st_code << 5);
if (pf_bit) if (pf_bit)
senddiag_cdb[1] |= 0x10; senddiag_cdb[1] |= 0x10;
if (st_bit) if (st_bit)
senddiag_cdb[1] |= 0x4; senddiag_cdb[1] |= 0x4;
skipping to change at line 488 skipping to change at line 491
sg_get_command_str(senddiag_cdb, SEND_DIAGNOSTIC_CMDLEN, sg_get_command_str(senddiag_cdb, SEND_DIAGNOSTIC_CMDLEN,
false, sizeof(b), b)); false, sizeof(b), b));
if (vb > 1) { if (vb > 1) {
if (paramp && param_len) { if (paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_s); pr2ws(" %s parameter list:\n", cdb_s);
hex2stderr((const uint8_t *)paramp, param_len, -1); hex2stderr((const uint8_t *)paramp, param_len, -1);
} }
pr2ws(" %s timeout: %d seconds\n", cdb_s, tmout); pr2ws(" %s timeout: %d seconds\n", cdb_s, tmout);
} }
} }
if (ptvp) {
set_scsi_pt_cdb(ptvp, senddiag_cdb, sizeof(senddiag_cdb)); ptvp_given = true;
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); partial_clear_scsi_pt_obj(ptvp);
if (get_scsi_pt_cdb_buf(ptvp))
local_cdb = false; /* N.B. Ignores locally built cdb */
else
set_scsi_pt_cdb(ptvp, senddiag_cdb, sizeof(senddiag_cdb));
if (get_scsi_pt_sense_buf(ptvp))
local_sense = false;
else
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
} else {
ptvp = construct_scsi_pt_obj_with_fd(sg_fd, vb);
if (NULL == ptvp)
return sg_convert_errno(ENOMEM);
set_scsi_pt_cdb(ptvp, senddiag_cdb, sizeof(senddiag_cdb));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
}
set_scsi_pt_data_out(ptvp, (uint8_t *)paramp, param_len); set_scsi_pt_data_out(ptvp, (uint8_t *)paramp, param_len);
res = do_scsi_pt(ptvp, -1, tmout, vb); res = do_scsi_pt(ptvp, -1, tmout, vb);
ret = sg_cmds_process_resp(ptvp, cdb_s, res, noisy, vb, &s_cat); ret = sg_cmds_process_resp(ptvp, cdb_s, res, noisy, vb, &s_cat);
if (-1 == ret) if (-1 == ret)
ret = sg_convert_errno(get_scsi_pt_os_err(ptvp)); ret = sg_convert_errno(get_scsi_pt_os_err(ptvp));
else if (-2 == ret) { else if (-2 == ret) {
switch (s_cat) { switch (s_cat) {
case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE: case SG_LIB_CAT_NO_SENSE:
ret = 0; ret = 0;
break; break;
default: default:
ret = s_cat; ret = s_cat;
break; break;
} }
} else } else
ret = 0; ret = 0;
if (ptvp_given) {
if (local_sense) /* stop caller trying to access local sense */
set_scsi_pt_sense(ptvp, NULL, 0);
if (local_cdb)
set_scsi_pt_cdb(ptvp, NULL, 0);
} else {
if (ptvp)
destruct_scsi_pt_obj(ptvp);
}
return ret; return ret;
} }
int int
sg_ll_send_diag_pt(struct sg_pt_base * ptvp, int st_code, bool pf_bit,
bool st_bit, bool devofl_bit, bool unitofl_bit,
int long_duration, void * paramp, int param_len,
bool noisy, int vb)
{
return sg_ll_send_diag_com(ptvp, -1, st_code, pf_bit, st_bit, devofl_bit,
unitofl_bit, long_duration, paramp,
param_len, noisy, vb);
}
int
sg_ll_send_diag(int sg_fd, int st_code, bool pf_bit, bool st_bit, sg_ll_send_diag(int sg_fd, int st_code, bool pf_bit, bool st_bit,
bool devofl_bit, bool unitofl_bit, int long_duration, bool devofl_bit, bool unitofl_bit, int long_duration,
void * paramp, int param_len, bool noisy, int vb) void * paramp, int param_len, bool noisy, int vb)
{ {
int ret; return sg_ll_send_diag_com(NULL, sg_fd, st_code, pf_bit, st_bit,
struct sg_pt_base * ptvp; devofl_bit, unitofl_bit, long_duration, paramp,
param_len, noisy, vb);
ptvp = construct_scsi_pt_obj_with_fd(sg_fd, vb);
if (NULL == ptvp)
return sg_convert_errno(ENOMEM);
ret = sg_ll_send_diag_pt(ptvp, st_code, pf_bit, st_bit, devofl_bit,
unitofl_bit, long_duration, paramp, param_len,
noisy, vb);
destruct_scsi_pt_obj(ptvp);
return ret;
} }
/* Invokes a SCSI RECEIVE DIAGNOSTIC RESULTS command. Return of 0 -> success, /* Invokes a SCSI RECEIVE DIAGNOSTIC RESULTS command. Return of 0 -> success,
* various SG_LIB_CAT_* positive values or -1 -> other errors */ * various SG_LIB_CAT_* positive values or -1 -> other errors */
int static int
sg_ll_receive_diag_pt(struct sg_pt_base * ptvp, bool pcv, int pg_code, sg_ll_receive_diag_com(struct sg_pt_base * ptvp, int sg_fd, bool pcv,
void * resp, int mx_resp_len, int timeout_secs, int pg_code, void * resp, int mx_resp_len,
int * residp, bool noisy, int vb) int timeout_secs, int * residp, bool noisy, int vb)
{ {
bool ptvp_given = false;
bool local_sense = true;
bool local_cdb = true;
int resid = 0; int resid = 0;
int res, ret, s_cat; int res, ret, s_cat;
static const char * const cdb_s = "Receive diagnostic results"; static const char * const cdb_s = "Receive diagnostic results";
uint8_t rcvdiag_cdb[RECEIVE_DIAGNOSTICS_CMDLEN] = uint8_t rcvdiag_cdb[RECEIVE_DIAGNOSTICS_CMDLEN] =
{RECEIVE_DIAGNOSTICS_CMD, 0, 0, 0, 0, 0}; {RECEIVE_DIAGNOSTICS_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN]; uint8_t sense_b[SENSE_BUFF_LEN];
if (pcv) if (pcv)
rcvdiag_cdb[1] = 0x1; rcvdiag_cdb[1] = 0x1;
rcvdiag_cdb[2] = (uint8_t)(pg_code); rcvdiag_cdb[2] = (uint8_t)(pg_code);
skipping to change at line 559 skipping to change at line 592
if (vb) { if (vb) {
char b[128]; char b[128];
pr2ws(" %s cdb: %s\n", cdb_s, pr2ws(" %s cdb: %s\n", cdb_s,
sg_get_command_str(rcvdiag_cdb, RECEIVE_DIAGNOSTICS_CMDLEN, sg_get_command_str(rcvdiag_cdb, RECEIVE_DIAGNOSTICS_CMDLEN,
false, sizeof(b), b)); false, sizeof(b), b));
} }
if (timeout_secs <= 0) if (timeout_secs <= 0)
timeout_secs = DEF_PT_TIMEOUT; timeout_secs = DEF_PT_TIMEOUT;
set_scsi_pt_cdb(ptvp, rcvdiag_cdb, sizeof(rcvdiag_cdb)); if (ptvp) {
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); ptvp_given = true;
partial_clear_scsi_pt_obj(ptvp);
if (get_scsi_pt_cdb_buf(ptvp))
local_cdb = false; /* N.B. Ignores locally built cdb */
else
set_scsi_pt_cdb(ptvp, rcvdiag_cdb, sizeof(rcvdiag_cdb));
if (get_scsi_pt_sense_buf(ptvp))
local_sense = false;
else
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
} else {
ptvp = construct_scsi_pt_obj_with_fd(sg_fd, vb);
if (NULL == ptvp)
return sg_convert_errno(ENOMEM);
set_scsi_pt_cdb(ptvp, rcvdiag_cdb, sizeof(rcvdiag_cdb));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
}
set_scsi_pt_data_in(ptvp, (uint8_t *)resp, mx_resp_len); set_scsi_pt_data_in(ptvp, (uint8_t *)resp, mx_resp_len);
res = do_scsi_pt(ptvp, -1, timeout_secs, vb); res = do_scsi_pt(ptvp, -1, timeout_secs, vb);
ret = sg_cmds_process_resp(ptvp, cdb_s, res, noisy, vb, &s_cat); ret = sg_cmds_process_resp(ptvp, cdb_s, res, noisy, vb, &s_cat);
resid = get_scsi_pt_resid(ptvp); resid = get_scsi_pt_resid(ptvp);
if (residp) if (residp)
*residp = resid; *residp = resid;
if (-1 == ret) if (-1 == ret)
ret = sg_convert_errno(get_scsi_pt_os_err(ptvp)); ret = sg_convert_errno(get_scsi_pt_os_err(ptvp));
else if (-2 == ret) { else if (-2 == ret) {
switch (s_cat) { switch (s_cat) {
skipping to change at line 593 skipping to change at line 642
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : "")); pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
hex2stderr((const uint8_t *)resp, (ret > 256 ? 256 : ret), hex2stderr((const uint8_t *)resp, (ret > 256 ? 256 : ret),
-1); -1);
} else { } else {
pr2ws(":\n"); pr2ws(":\n");
hex2stderr((const uint8_t *)resp, ret, 0); hex2stderr((const uint8_t *)resp, ret, 0);
} }
} }
ret = 0; ret = 0;
} }
if (ptvp_given) {
if (local_sense) /* stop caller trying to access local sense */
set_scsi_pt_sense(ptvp, NULL, 0);
if (local_cdb)
set_scsi_pt_cdb(ptvp, NULL, 0);
} else {
if (ptvp)
destruct_scsi_pt_obj(ptvp);
}
return ret; return ret;
} }
int
sg_ll_receive_diag_pt(struct sg_pt_base * ptvp, bool pcv, int pg_code,
void * resp, int mx_resp_len, int timeout_secs,
int * residp, bool noisy, int vb)
{
return sg_ll_receive_diag_com(ptvp, -1, pcv, pg_code, resp, mx_resp_len,
timeout_secs, residp, noisy, vb);
}
/* Invokes a SCSI RECEIVE DIAGNOSTIC RESULTS command. Return of 0 -> success, /* Invokes a SCSI RECEIVE DIAGNOSTIC RESULTS command. Return of 0 -> success,
* various SG_LIB_CAT_* positive values or -1 -> other errors */ * various SG_LIB_CAT_* positive values or -1 -> other errors */
int int
sg_ll_receive_diag(int sg_fd, bool pcv, int pg_code, void * resp, sg_ll_receive_diag(int sg_fd, bool pcv, int pg_code, void * resp,
int mx_resp_len, bool noisy, int vb) int mx_resp_len, bool noisy, int vb)
{ {
int ret; return sg_ll_receive_diag_com(NULL, sg_fd, pcv, pg_code, resp,
struct sg_pt_base * ptvp; mx_resp_len, 0, NULL, noisy, vb);
ptvp = construct_scsi_pt_obj_with_fd(sg_fd, vb);
if (NULL == ptvp)
return sg_convert_errno(ENOMEM);
ret = sg_ll_receive_diag_pt(ptvp, pcv, pg_code, resp, mx_resp_len, 0,
NULL, noisy, vb);
destruct_scsi_pt_obj(ptvp);
return ret;
} }
int int
sg_ll_receive_diag_v2(int sg_fd, bool pcv, int pg_code, void * resp, sg_ll_receive_diag_v2(int sg_fd, bool pcv, int pg_code, void * resp,
int mx_resp_len, int timeout_secs, int * residp, int mx_resp_len, int timeout_secs, int * residp,
bool noisy, int vb) bool noisy, int vb)
{ {
int ret; return sg_ll_receive_diag_com(NULL, sg_fd, pcv, pg_code, resp,
struct sg_pt_base * ptvp; mx_resp_len, timeout_secs, residp, noisy,
vb);
ptvp = construct_scsi_pt_obj_with_fd(sg_fd, vb);
if (NULL == ptvp)
return sg_convert_errno(ENOMEM);
ret = sg_ll_receive_diag_pt(ptvp, pcv, pg_code, resp, mx_resp_len,
timeout_secs, residp, noisy, vb);
destruct_scsi_pt_obj(ptvp);
return ret;
} }
/* Invokes a SCSI READ DEFECT DATA (10) command (SBC). Return of 0 -> success /* Invokes a SCSI READ DEFECT DATA (10) command (SBC). Return of 0 -> success
* various SG_LIB_CAT_* positive values or -1 -> other errors */ * various SG_LIB_CAT_* positive values or -1 -> other errors */
int int
sg_ll_read_defect10(int sg_fd, bool req_plist, bool req_glist, int dl_format, sg_ll_read_defect10(int sg_fd, bool req_plist, bool req_glist, int dl_format,
void * resp, int mx_resp_len, bool noisy, int vb) void * resp, int mx_resp_len, bool noisy, int vb)
{ {
static const char * const cdb_s = "Read defect(10)"; static const char * const cdb_s = "Read defect(10)";
int res, ret, s_cat; int res, ret, s_cat;
 End of changes. 13 change blocks. 
46 lines changed or deleted 99 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)