aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc
diff options
context:
space:
mode:
authorBhanu Prakash Gollapudi <bprakash@broadcom.com>2010-06-11 19:43:54 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:01:45 -0400
commit618461c02b00a658ec8aa07d409cd496a7e254e2 (patch)
treed4e3baa7fee94a79c8882c85f93422a45a9be5a2 /drivers/scsi/libfc
parent292e40b956982601dfc61fe8f0470eb18a616d7e (diff)
[SCSI] libfc: Honor LS_ACC response codes for PRLI
As per FC-LS Rev 1.62 table 46, response codes are handled as follows: 1. If the Req executed is true, PRLI is accepted. 2. If Req executed is not set, if resp code is 5, PRLI is not retried and port is logged out. 3. If resp code is anything apart from 1 or 5, PRLI is retired upto max retry count. Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r--drivers/scsi/libfc/fc_rport.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 3ee497a05168..e33c5c7961a2 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -698,6 +698,7 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
698 u32 roles = FC_RPORT_ROLE_UNKNOWN; 698 u32 roles = FC_RPORT_ROLE_UNKNOWN;
699 u32 fcp_parm = 0; 699 u32 fcp_parm = 0;
700 u8 op; 700 u8 op;
701 u8 resp_code = 0;
701 702
702 mutex_lock(&rdata->rp_mutex); 703 mutex_lock(&rdata->rp_mutex);
703 704
@@ -722,11 +723,25 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
722 op = fc_frame_payload_op(fp); 723 op = fc_frame_payload_op(fp);
723 if (op == ELS_LS_ACC) { 724 if (op == ELS_LS_ACC) {
724 pp = fc_frame_payload_get(fp, sizeof(*pp)); 725 pp = fc_frame_payload_get(fp, sizeof(*pp));
725 if (pp && pp->prli.prli_spp_len >= sizeof(pp->spp)) { 726 if (!pp)
726 fcp_parm = ntohl(pp->spp.spp_params); 727 goto out;
727 if (fcp_parm & FCP_SPPF_RETRY) 728
728 rdata->flags |= FC_RP_FLAGS_RETRY; 729 resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK);
730 FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x\n",
731 pp->spp.spp_flags);
732 if (resp_code != FC_SPP_RESP_ACK) {
733 if (resp_code == FC_SPP_RESP_CONF)
734 fc_rport_error(rdata, fp);
735 else
736 fc_rport_error_retry(rdata, fp);
737 goto out;
729 } 738 }
739 if (pp->prli.prli_spp_len < sizeof(pp->spp))
740 goto out;
741
742 fcp_parm = ntohl(pp->spp.spp_params);
743 if (fcp_parm & FCP_SPPF_RETRY)
744 rdata->flags |= FC_RP_FLAGS_RETRY;
730 745
731 rdata->supported_classes = FC_COS_CLASS3; 746 rdata->supported_classes = FC_COS_CLASS3;
732 if (fcp_parm & FCP_SPPF_INIT_FCN) 747 if (fcp_parm & FCP_SPPF_INIT_FCN)