Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Bhanu Prakash Gollapudi and committed by
James Bottomley
618461c0 292e40b9

+19 -4
+19 -4
drivers/scsi/libfc/fc_rport.c
··· 698 698 u32 roles = FC_RPORT_ROLE_UNKNOWN; 699 699 u32 fcp_parm = 0; 700 700 u8 op; 701 + u8 resp_code = 0; 701 702 702 703 mutex_lock(&rdata->rp_mutex); 703 704 ··· 723 722 op = fc_frame_payload_op(fp); 724 723 if (op == ELS_LS_ACC) { 725 724 pp = fc_frame_payload_get(fp, sizeof(*pp)); 726 - if (pp && pp->prli.prli_spp_len >= sizeof(pp->spp)) { 727 - fcp_parm = ntohl(pp->spp.spp_params); 728 - if (fcp_parm & FCP_SPPF_RETRY) 729 - rdata->flags |= FC_RP_FLAGS_RETRY; 725 + if (!pp) 726 + goto out; 727 + 728 + resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK); 729 + FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x\n", 730 + pp->spp.spp_flags); 731 + if (resp_code != FC_SPP_RESP_ACK) { 732 + if (resp_code == FC_SPP_RESP_CONF) 733 + fc_rport_error(rdata, fp); 734 + else 735 + fc_rport_error_retry(rdata, fp); 736 + goto out; 730 737 } 738 + if (pp->prli.prli_spp_len < sizeof(pp->spp)) 739 + goto out; 740 + 741 + fcp_parm = ntohl(pp->spp.spp_params); 742 + if (fcp_parm & FCP_SPPF_RETRY) 743 + rdata->flags |= FC_RP_FLAGS_RETRY; 731 744 732 745 rdata->supported_classes = FC_COS_CLASS3; 733 746 if (fcp_parm & FCP_SPPF_INIT_FCN)