aboutsummaryrefslogtreecommitdiff
path: root/src/sg_copy_results.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2012-09-18 12:39:47 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2012-09-18 12:39:47 +0000
commitd2105f93d0db6ddbdcf262be13fbabe4000e6149 (patch)
tree33ac0c6d8f069af2677c3e6a0fa2d7371a25d158 /src/sg_copy_results.c
parent19776eb6029a597dcec752989933a8c12a9be0a8 (diff)
downloadsg3_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.c72
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;