aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_vport.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-08-24 21:49:45 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-10-13 09:28:53 -0400
commit90160e010b6f3a91a9bb044bbe6723731e6f366c (patch)
tree8320400d5bed96f1976cef88adcad647fcb48f9e /drivers/scsi/lpfc/lpfc_vport.c
parente59058c44025d71c9b7f260076a932935d3bba95 (diff)
[SCSI] lpfc 8.2.8 : Miscellaneous Discovery Fixes
Miscellaneous Discovery fixes: - Fix rejection followed by acceptance in handling RPL and RPS unsolicited events - Fix for vport delete crash - Fix PLOGI vs ADISC race condition Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_vport.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index 109f89d98830..ad0f65313878 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -204,6 +204,77 @@ lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport)
204 return 1; 204 return 1;
205} 205}
206 206
207/**
208 * lpfc_discovery_wait: Wait for driver discovery to quiesce.
209 * @vport: The virtual port for which this call is being executed.
210 *
211 * This driver calls this routine specifically from lpfc_vport_delete
212 * to enforce a synchronous execution of vport
213 * delete relative to discovery activities. The
214 * lpfc_vport_delete routine should not return until it
215 * can reasonably guarantee that discovery has quiesced.
216 * Post FDISC LOGO, the driver must wait until its SAN teardown is
217 * complete and all resources recovered before allowing
218 * cleanup.
219 *
220 * This routine does not require any locks held.
221 **/
222static void lpfc_discovery_wait(struct lpfc_vport *vport)
223{
224 struct lpfc_hba *phba = vport->phba;
225 uint32_t wait_flags = 0;
226 unsigned long wait_time_max;
227 unsigned long start_time;
228
229 wait_flags = FC_RSCN_MODE | FC_RSCN_DISCOVERY | FC_NLP_MORE |
230 FC_RSCN_DEFERRED | FC_NDISC_ACTIVE | FC_DISC_TMO;
231
232 /*
233 * The time constraint on this loop is a balance between the
234 * fabric RA_TOV value and dev_loss tmo. The driver's
235 * devloss_tmo is 10 giving this loop a 3x multiplier minimally.
236 */
237 wait_time_max = msecs_to_jiffies(((phba->fc_ratov * 3) + 3) * 1000);
238 wait_time_max += jiffies;
239 start_time = jiffies;
240 while (time_before(jiffies, wait_time_max)) {
241 if ((vport->num_disc_nodes > 0) ||
242 (vport->fc_flag & wait_flags) ||
243 ((vport->port_state > LPFC_VPORT_FAILED) &&
244 (vport->port_state < LPFC_VPORT_READY))) {
245 lpfc_printf_log(phba, KERN_INFO, LOG_VPORT,
246 "1833 Vport discovery quiesce Wait:"
247 " vpi x%x state x%x fc_flags x%x"
248 " num_nodes x%x, waiting 1000 msecs"
249 " total wait msecs x%x\n",
250 vport->vpi, vport->port_state,
251 vport->fc_flag, vport->num_disc_nodes,
252 jiffies_to_msecs(jiffies - start_time));
253 msleep(1000);
254 } else {
255 /* Base case. Wait variants satisfied. Break out */
256 lpfc_printf_log(phba, KERN_INFO, LOG_VPORT,
257 "1834 Vport discovery quiesced:"
258 " vpi x%x state x%x fc_flags x%x"
259 " wait msecs x%x\n",
260 vport->vpi, vport->port_state,
261 vport->fc_flag,
262 jiffies_to_msecs(jiffies
263 - start_time));
264 break;
265 }
266 }
267
268 if (time_after(jiffies, wait_time_max))
269 lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
270 "1835 Vport discovery quiesce failed:"
271 " vpi x%x state x%x fc_flags x%x"
272 " wait msecs x%x\n",
273 vport->vpi, vport->port_state,
274 vport->fc_flag,
275 jiffies_to_msecs(jiffies - start_time));
276}
277
207int 278int
208lpfc_vport_create(struct fc_vport *fc_vport, bool disable) 279lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
209{ 280{
@@ -602,6 +673,9 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
602 timeout = schedule_timeout(timeout); 673 timeout = schedule_timeout(timeout);
603 } 674 }
604 675
676 if (!(phba->pport->load_flag & FC_UNLOADING))
677 lpfc_discovery_wait(vport);
678
605skip_logo: 679skip_logo:
606 lpfc_cleanup(vport); 680 lpfc_cleanup(vport);
607 lpfc_sli_host_down(vport); 681 lpfc_sli_host_down(vport);