diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2012-09-18 12:39:47 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2012-09-18 12:39:47 +0000 |
commit | d2105f93d0db6ddbdcf262be13fbabe4000e6149 (patch) | |
tree | 33ac0c6d8f069af2677c3e6a0fa2d7371a25d158 /src/sg_copy_results.c | |
parent | 19776eb6029a597dcec752989933a8c12a9be0a8 (diff) | |
download | sg3_utils-d2105f93d0db6ddbdcf262be13fbabe4000e6149.tar.gz |
sg_copy_results: source and manpage updates
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@455 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src/sg_copy_results.c')
-rw-r--r-- | src/sg_copy_results.c | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/src/sg_copy_results.c b/src/sg_copy_results.c index 5b986958..2a3bae81 100644 --- a/src/sg_copy_results.c +++ b/src/sg_copy_results.c @@ -47,10 +47,10 @@ static char * version_str = "1.1 20120905"; struct descriptor_type { int code; - char desc[]; + char desc[124]; }; -struct descriptor_type target_descriptor_codes [] = { +struct descriptor_type target_descriptor_codes[] = { { 0xe0, "Fibre Channel N_Port_Name"}, { 0xe1, "Fibre Channel N_port_ID"}, { 0xe2, "Fibre Channesl N_port_ID with N_Port_Name checking"}, @@ -62,7 +62,8 @@ struct descriptor_type target_descriptor_codes [] = { { 0xe8, "IEEE 1395 EUI-64" }, { 0xe9, "SAS Serial SCSI Protocol" }, { 0xea, "IPv6" }, - { 0xeb, "IP Copy Service" } + { 0xeb, "IP Copy Service" }, + { -1, "" } }; struct descriptor_type segment_descriptor_codes [] = { @@ -93,10 +94,40 @@ struct descriptor_type segment_descriptor_codes [] = { { 0x13, "Image copy from sequential-access device to sequential-access " "device" }, { 0x14, "Register persistent reservation key" }, - { 0x15, "Third party persistent reservations source I_T nexus" } + { 0x15, "Third party persistent reservations source I_T nexus" }, + { -1, "" } }; static void +scsi_failed_segment_details(unsigned char *rcBuff, unsigned int rcBuffLen) +{ + unsigned int len; + char senseBuff[1024]; + int senseLen; + + if (rcBuffLen < 4) { + fprintf(stderr, " <<not enough data to procedd report>>\n"); + return; + } + len = (rcBuff[0] << 24) | (rcBuff[1] << 16) | (rcBuff[2] << 8) | + rcBuff[3]; + if (len + 3 > rcBuffLen) { + fprintf(stderr, " <<report too long for internal buffer," + " output truncated\n"); + } + if (len < 52) { + fprintf(stderr, " <<no segment details, response data length %d\n", + len); + return; + } + printf("Receive copy results (failed segment details):\n"); + printf(" Extended copy command status: %d\n", rcBuff[56]); + senseLen = (rcBuff[58] << 8) | rcBuff[59]; + sg_get_sense_str(" ", &rcBuff[60], senseLen, 0, 1024, senseBuff); + printf("%s", senseBuff); +} + +static void scsi_copy_status(unsigned char *rcBuff, unsigned int rcBuffLen) { unsigned int len; @@ -181,22 +212,33 @@ scsi_operating_parameters(unsigned char *rcBuff, unsigned int rcBuffLen) printf(" Held data granularity: %lu bytes\n", (unsigned long)(1 << rcBuff[39])); - printf(" Implemented descriptor list:\n "); + printf(" Implemented descriptor list:\n"); for (n = 0; n < rcBuff[43]; n++) { int code = rcBuff[44 + n]; if (code < 0x16) { - printf("Segment descriptor 0x%02x: %s\n", - code, segment_descriptor_codes[code].desc); + struct descriptor_type *seg_desc = segment_descriptor_codes; + while (strlen(seg_desc->desc)) { + if (seg_desc->code == code) + break; + seg_desc++; + } + printf(" Segment descriptor 0x%02x: %s\n", code, + strlen(seg_desc->desc) ? seg_desc->desc : "Reserved"); } else if (code < 0xc0) { - printf("Segment descriptor 0x%02x: Reserved\n", code); + printf(" Segment descriptor 0x%02x: Reserved\n", code); } else if (code < 0xe0) { - printf("Vendor specific descriptor 0x%02x\n", code); - } else if (code < 0xec) { - printf("Target descriptor 0x%02x: %s\n", - code, target_descriptor_codes[code - 0xe0].desc); + printf(" Vendor specific descriptor 0x%02x\n", code); } else { - printf("Target descriptor 0x%02x: Reserved\n", code); + struct descriptor_type *tgt_desc = target_descriptor_codes; + + while (strlen(tgt_desc->desc)) { + if (tgt_desc->code == code) + break; + tgt_desc++; + } + printf(" Target descriptor 0x%02x: %s\n", code, + strlen(tgt_desc->desc) ? tgt_desc->desc : "Reserved"); } } printf("\n"); @@ -396,6 +438,10 @@ main(int argc, char * argv[]) goto finish; } switch (sa) { + case 4: /* Failed segment details */ + scsi_failed_segment_details(cpResultBuff, xfer_len); + res = 0; + break; case 3: /* Operating parameters */ scsi_operating_parameters(cpResultBuff, xfer_len); res = 0; |