aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-08-02 11:10:31 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-08-01 13:24:10 -0400
commit51ef4c26891a734bc8416b639ad460a8162926bc (patch)
tree8279e11bf1a0a3200e8aa9bb3d956345ef73533c /drivers/scsi/lpfc/lpfc_els.c
parent78b2d852a88cd2a55e3ab632109de045d58b83e3 (diff)
[SCSI] lpfc 8.2.2 : Miscellaneous Bug Fixes
- Fix vport ndlp ref counting errors - Fix use after free of ndlp structure - Use the correct flag to check for LOADING setting. - Fix driver unload bugs (related to shost references) after link down or rscn - Fix up HBQ initialization - Fix port_list locking around driver unload. - Fix references to hostdata as a phba - Fix GFFID type offset to work correctly with big endian structure. - Only call pci_disable_msi if the pci_enable_msi succeeded - Fix vport_delete wait/fail if in discovery - Put a reference on the nameservers ndlp when performing CT traffic. - Remove unbalanced hba unlock. - Fix up HBQ processing - Fix lpfc debugfs discovery trace output for ELS rsp cmpl - Send ADISC when rpi is 0 - Stop FDISC retrying forever - Unable to retrieve correct config parameter for vport - Fix sli_validate_fcp_iocb, sli_sum_iocb, sli_abort_iocb to be vport-aware. - Fix index-out-of-range error in iocb. Spotted by Coverity. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c64
1 files changed, 32 insertions, 32 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 9365e19696e2..8085900635d4 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -196,9 +196,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
196 bpl->tus.w = le32_to_cpu(bpl->tus.w); 196 bpl->tus.w = le32_to_cpu(bpl->tus.w);
197 } 197 }
198 198
199 /* Save for completion so we can release these resources */ 199 elsiocb->context1 = lpfc_nlp_get(ndlp);
200 if (elscmd != ELS_CMD_LS_RJT)
201 elsiocb->context1 = lpfc_nlp_get(ndlp);
202 elsiocb->context2 = pcmd; 200 elsiocb->context2 = pcmd;
203 elsiocb->context3 = pbuflist; 201 elsiocb->context3 = pbuflist;
204 elsiocb->retry = retry; 202 elsiocb->retry = retry;
@@ -1809,8 +1807,10 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1809 "retrying...\n"); 1807 "retrying...\n");
1810 lpfc_mbx_unreg_vpi(vport); 1808 lpfc_mbx_unreg_vpi(vport);
1811 retry = 1; 1809 retry = 1;
1812 /* Always retry for this case */ 1810 /* FDISC retry policy */
1813 cmdiocb->retry = 0; 1811 maxretry = 48;
1812 if (cmdiocb->retry >= 32)
1813 delay = 1000;
1814 } 1814 }
1815 break; 1815 break;
1816 1816
@@ -1886,8 +1886,10 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1886 delay = 1000; 1886 delay = 1000;
1887 maxretry = 48; 1887 maxretry = 48;
1888 } else if (cmd == ELS_CMD_FDISC) { 1888 } else if (cmd == ELS_CMD_FDISC) {
1889 /* Always retry for this case */ 1889 /* FDISC retry policy */
1890 cmdiocb->retry = 0; 1890 maxretry = 48;
1891 if (cmdiocb->retry >= 32)
1892 delay = 1000;
1891 } 1893 }
1892 retry = 1; 1894 retry = 1;
1893 break; 1895 break;
@@ -2121,9 +2123,9 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2121 } 2123 }
2122 2124
2123 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, 2125 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2124 "ACC cmpl: status:x%x/x%x did:x%x", 2126 "ELS rsp cmpl: status:x%x/x%x did:x%x",
2125 irsp->ulpStatus, irsp->un.ulpWord[4], 2127 irsp->ulpStatus, irsp->un.ulpWord[4],
2126 irsp->un.rcvels.remoteID); 2128 cmdiocb->iocb.un.elsreq64.remoteID);
2127 /* ELS response tag <ulpIoTag> completes */ 2129 /* ELS response tag <ulpIoTag> completes */
2128 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, 2130 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2129 "0110 ELS response tag x%x completes " 2131 "0110 ELS response tag x%x completes "
@@ -2184,7 +2186,7 @@ out:
2184int 2186int
2185lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, 2187lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
2186 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp, 2188 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
2187 LPFC_MBOXQ_t *mbox, uint8_t newnode) 2189 LPFC_MBOXQ_t *mbox)
2188{ 2190{
2189 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 2191 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2190 struct lpfc_hba *phba = vport->phba; 2192 struct lpfc_hba *phba = vport->phba;
@@ -2270,11 +2272,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
2270 default: 2272 default:
2271 return 1; 2273 return 1;
2272 } 2274 }
2273
2274 if (newnode) {
2275 lpfc_nlp_put(ndlp);
2276 elsiocb->context1 = NULL;
2277 }
2278 /* Xmit ELS ACC response tag <ulpIoTag> */ 2275 /* Xmit ELS ACC response tag <ulpIoTag> */
2279 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, 2276 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2280 "0128 Xmit ELS ACC response tag x%x, XRI: x%x, " 2277 "0128 Xmit ELS ACC response tag x%x, XRI: x%x, "
@@ -2333,10 +2330,8 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
2333 pcmd += sizeof(uint32_t); 2330 pcmd += sizeof(uint32_t);
2334 *((uint32_t *) (pcmd)) = rejectError; 2331 *((uint32_t *) (pcmd)) = rejectError;
2335 2332
2336 if (mbox) { 2333 if (mbox)
2337 elsiocb->context_un.mbox = mbox; 2334 elsiocb->context_un.mbox = mbox;
2338 elsiocb->context1 = lpfc_nlp_get(ndlp);
2339 }
2340 2335
2341 /* Xmit ELS RJT <err> response tag <ulpIoTag> */ 2336 /* Xmit ELS RJT <err> response tag <ulpIoTag> */
2342 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, 2337 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
@@ -2353,6 +2348,15 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
2353 phba->fc_stat.elsXmitLSRJT++; 2348 phba->fc_stat.elsXmitLSRJT++;
2354 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; 2349 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
2355 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); 2350 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
2351
2352 /* If the node is in the UNUSED state, and we are sending
2353 * a reject, we are done with it. Release driver reference
2354 * count here. The outstanding els will release its reference on
2355 * completion and the node can be freed then.
2356 */
2357 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
2358 lpfc_nlp_put(ndlp);
2359
2356 if (rc == IOCB_ERROR) { 2360 if (rc == IOCB_ERROR) {
2357 lpfc_els_free_iocb(phba, elsiocb); 2361 lpfc_els_free_iocb(phba, elsiocb);
2358 return 1; 2362 return 1;
@@ -2747,7 +2751,7 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
2747 2751
2748static int 2752static int
2749lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, 2753lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2750 struct lpfc_nodelist *ndlp, uint8_t newnode) 2754 struct lpfc_nodelist *ndlp)
2751{ 2755{
2752 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 2756 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2753 struct lpfc_hba *phba = vport->phba; 2757 struct lpfc_hba *phba = vport->phba;
@@ -2781,8 +2785,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2781 "RCV RSCN ignore: did:x%x/ste:x%x flg:x%x", 2785 "RCV RSCN ignore: did:x%x/ste:x%x flg:x%x",
2782 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); 2786 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
2783 2787
2784 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 2788 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
2785 newnode);
2786 return 0; 2789 return 0;
2787 } 2790 }
2788 2791
@@ -2814,7 +2817,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2814 ndlp->nlp_flag); 2817 ndlp->nlp_flag);
2815 2818
2816 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, 2819 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb,
2817 ndlp, NULL, newnode); 2820 ndlp, NULL);
2818 return 0; 2821 return 0;
2819 } 2822 }
2820 } 2823 }
@@ -2870,8 +2873,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2870 vport->port_state); 2873 vport->port_state);
2871 } 2874 }
2872 /* Send back ACC */ 2875 /* Send back ACC */
2873 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 2876 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
2874 newnode);
2875 2877
2876 /* send RECOVERY event for ALL nodes that match RSCN payload */ 2878 /* send RECOVERY event for ALL nodes that match RSCN payload */
2877 lpfc_rscn_recovery_check(vport); 2879 lpfc_rscn_recovery_check(vport);
@@ -2896,7 +2898,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2896 lpfc_set_disctmo(vport); 2898 lpfc_set_disctmo(vport);
2897 2899
2898 /* Send back ACC */ 2900 /* Send back ACC */
2899 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode); 2901 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
2900 2902
2901 /* send RECOVERY event for ALL nodes that match RSCN payload */ 2903 /* send RECOVERY event for ALL nodes that match RSCN payload */
2902 lpfc_rscn_recovery_check(vport); 2904 lpfc_rscn_recovery_check(vport);
@@ -2965,7 +2967,7 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport)
2965 2967
2966static int 2968static int
2967lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, 2969lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2968 struct lpfc_nodelist *ndlp, uint8_t newnode) 2970 struct lpfc_nodelist *ndlp)
2969{ 2971{
2970 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 2972 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2971 struct lpfc_hba *phba = vport->phba; 2973 struct lpfc_hba *phba = vport->phba;
@@ -3048,7 +3050,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3048 } 3050 }
3049 3051
3050 /* Send back ACC */ 3052 /* Send back ACC */
3051 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode); 3053 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
3052 3054
3053 return 0; 3055 return 0;
3054} 3056}
@@ -3409,7 +3411,7 @@ lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3409 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, 3411 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3410 "0600 FARP-RSP received from DID x%x\n", did); 3412 "0600 FARP-RSP received from DID x%x\n", did);
3411 /* ACCEPT the Farp resp request */ 3413 /* ACCEPT the Farp resp request */
3412 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); 3414 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
3413 3415
3414 return 0; 3416 return 0;
3415} 3417}
@@ -3791,7 +3793,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3791 did, vport->port_state, ndlp->nlp_flag); 3793 did, vport->port_state, ndlp->nlp_flag);
3792 3794
3793 phba->fc_stat.elsRcvFLOGI++; 3795 phba->fc_stat.elsRcvFLOGI++;
3794 lpfc_els_rcv_flogi(vport, elsiocb, ndlp, newnode); 3796 lpfc_els_rcv_flogi(vport, elsiocb, ndlp);
3795 if (newnode) 3797 if (newnode)
3796 lpfc_drop_node(vport, ndlp); 3798 lpfc_drop_node(vport, ndlp);
3797 break; 3799 break;
@@ -3821,7 +3823,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3821 break; 3823 break;
3822 case ELS_CMD_RSCN: 3824 case ELS_CMD_RSCN:
3823 phba->fc_stat.elsRcvRSCN++; 3825 phba->fc_stat.elsRcvRSCN++;
3824 lpfc_els_rcv_rscn(vport, elsiocb, ndlp, newnode); 3826 lpfc_els_rcv_rscn(vport, elsiocb, ndlp);
3825 if (newnode) 3827 if (newnode)
3826 lpfc_drop_node(vport, ndlp); 3828 lpfc_drop_node(vport, ndlp);
3827 break; 3829 break;
@@ -3951,8 +3953,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3951 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; 3953 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
3952 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp, 3954 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp,
3953 NULL); 3955 NULL);
3954 if (newnode)
3955 lpfc_drop_node(vport, ndlp);
3956 } 3956 }
3957 3957
3958 return; 3958 return;