summaryrefslogtreecommitdiffstats
path: root/include/scsi/fc
diff options
context:
space:
mode:
authorYi Zou <yi.zou@intel.com>2012-09-24 11:52:50 -0700
committerJames Bottomley <JBottomley@Parallels.com>2012-10-07 11:52:55 +0100
commit3b64b1881143ce9e461c211cc81acc72d0cdc476 (patch)
tree4a4869002d37f8b3257ae442caa67b5071e69fed /include/scsi/fc
parent31c37a6f21d86e6bca095b71d603ed543ae070ad (diff)
[SCSI] libfc: fix lun reset failure bugs in fc_fcp_resp handling of FCP_RSP_INFO
In LUN RESET testing involving NetApp targets, it is observed that LUN RESET is failing. The fc_fcp_resp() is not completing the completion for the LUN RESET task since fc_fcp_resp assumes that the FCP_RSP_INFO is 8 bytes with the 4 byte reserved field, where in case of NetApp targets the FCP_RSP to LUN RESET only has 4 bytes of FCP_RSP_INFO. This leads fc_fcp_resp to error out w/o completing the task completion, eventually causing LUN RESET to be escalated to host reset, which is not very nice. Per FCP-3 r04, clause 9.5.15 and Table 23, the FCP_RSP_INFO field can be either 4 bytes or 8 bytes, with the last 4 bytes as "Reserved (if any)". Therefore it is valid to have 4 bytes FCP_RSP_INFO like some of the NetApp targets behave. Fixing this by validating the FCP_RSP_INFO against both the two spec allowed length. Reported-by: Frank Zhang <frank_1.zhang@intel.com> Signed-off-by: Yi Zou <yi.zou@intel.com> Tested-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'include/scsi/fc')
-rw-r--r--include/scsi/fc/fc_fcp.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h
index 0d7d67e96d4..9c8702942b6 100644
--- a/include/scsi/fc/fc_fcp.h
+++ b/include/scsi/fc/fc_fcp.h
@@ -127,6 +127,9 @@ struct fcp_txrdy {
*
* All response frames will always contain the fcp_resp template. Some
* will also include the fcp_resp_len template.
+ *
+ * From Table 23, the FCP_RSP_INFO can either be 4 bytes or 8 bytes, both
+ * are valid length.
*/
struct fcp_resp {
__u8 _fr_resvd[8]; /* reserved */
@@ -156,6 +159,9 @@ struct fcp_resp_rsp_info {
__u8 _fr_resvd2[4]; /* reserved */
};
+#define FCP_RESP_RSP_INFO_LEN4 4 /* without reserved field */
+#define FCP_RESP_RSP_INFO_LEN8 8 /* with reserved field */
+
struct fcp_resp_with_ext {
struct fcp_resp resp;
struct fcp_resp_ext ext;