diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 1245 |
1 files changed, 680 insertions, 565 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 61caa8d379e2..dee875ee6165 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -54,7 +54,7 @@ static uint8_t lpfcAlpaArray[] = { | |||
54 | 0x10, 0x0F, 0x08, 0x04, 0x02, 0x01 | 54 | 0x10, 0x0F, 0x08, 0x04, 0x02, 0x01 |
55 | }; | 55 | }; |
56 | 56 | ||
57 | static void lpfc_disc_timeout_handler(struct lpfc_hba *); | 57 | static void lpfc_disc_timeout_handler(struct lpfc_vport *); |
58 | 58 | ||
59 | void | 59 | void |
60 | lpfc_terminate_rport_io(struct fc_rport *rport) | 60 | lpfc_terminate_rport_io(struct fc_rport *rport) |
@@ -74,14 +74,12 @@ lpfc_terminate_rport_io(struct fc_rport *rport) | |||
74 | return; | 74 | return; |
75 | } | 75 | } |
76 | 76 | ||
77 | phba = ndlp->nlp_phba; | 77 | phba = ndlp->vport->phba; |
78 | 78 | ||
79 | spin_lock_irq(phba->host->host_lock); | ||
80 | if (ndlp->nlp_sid != NLP_NO_SID) { | 79 | if (ndlp->nlp_sid != NLP_NO_SID) { |
81 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], | 80 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], |
82 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); | 81 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); |
83 | } | 82 | } |
84 | spin_unlock_irq(phba->host->host_lock); | ||
85 | 83 | ||
86 | return; | 84 | return; |
87 | } | 85 | } |
@@ -97,6 +95,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
97 | uint8_t *name; | 95 | uint8_t *name; |
98 | int warn_on = 0; | 96 | int warn_on = 0; |
99 | struct lpfc_hba *phba; | 97 | struct lpfc_hba *phba; |
98 | struct lpfc_vport *vport; | ||
100 | 99 | ||
101 | rdata = rport->dd_data; | 100 | rdata = rport->dd_data; |
102 | ndlp = rdata->pnode; | 101 | ndlp = rdata->pnode; |
@@ -113,9 +112,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
113 | return; | 112 | return; |
114 | 113 | ||
115 | name = (uint8_t *)&ndlp->nlp_portname; | 114 | name = (uint8_t *)&ndlp->nlp_portname; |
116 | phba = ndlp->nlp_phba; | 115 | vport = ndlp->vport; |
117 | 116 | phba = vport->phba; | |
118 | spin_lock_irq(phba->host->host_lock); | ||
119 | 117 | ||
120 | if (ndlp->nlp_sid != NLP_NO_SID) { | 118 | if (ndlp->nlp_sid != NLP_NO_SID) { |
121 | warn_on = 1; | 119 | warn_on = 1; |
@@ -123,11 +121,9 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
123 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], | 121 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], |
124 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); | 122 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); |
125 | } | 123 | } |
126 | if (phba->fc_flag & FC_UNLOADING) | 124 | if (vport->load_flag & FC_UNLOADING) |
127 | warn_on = 0; | 125 | warn_on = 0; |
128 | 126 | ||
129 | spin_unlock_irq(phba->host->host_lock); | ||
130 | |||
131 | if (warn_on) { | 127 | if (warn_on) { |
132 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 128 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
133 | "%d:0203 Devloss timeout on " | 129 | "%d:0203 Devloss timeout on " |
@@ -150,11 +146,11 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
150 | ndlp->nlp_state, ndlp->nlp_rpi); | 146 | ndlp->nlp_state, ndlp->nlp_rpi); |
151 | } | 147 | } |
152 | 148 | ||
153 | if (!(phba->fc_flag & FC_UNLOADING) && | 149 | if (!(vport->load_flag & FC_UNLOADING) && |
154 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && | 150 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && |
155 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 151 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
156 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) | 152 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) |
157 | lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM); | 153 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); |
158 | else { | 154 | else { |
159 | rdata->pnode = NULL; | 155 | rdata->pnode = NULL; |
160 | ndlp->rport = NULL; | 156 | ndlp->rport = NULL; |
@@ -166,33 +162,33 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
166 | } | 162 | } |
167 | 163 | ||
168 | static void | 164 | static void |
169 | lpfc_work_list_done(struct lpfc_hba * phba) | 165 | lpfc_work_list_done(struct lpfc_hba *phba) |
170 | { | 166 | { |
171 | struct lpfc_work_evt *evtp = NULL; | 167 | struct lpfc_work_evt *evtp = NULL; |
172 | struct lpfc_nodelist *ndlp; | 168 | struct lpfc_nodelist *ndlp; |
173 | int free_evt; | 169 | int free_evt; |
174 | 170 | ||
175 | spin_lock_irq(phba->host->host_lock); | 171 | spin_lock_irq(&phba->hbalock); |
176 | while(!list_empty(&phba->work_list)) { | 172 | while (!list_empty(&phba->work_list)) { |
177 | list_remove_head((&phba->work_list), evtp, typeof(*evtp), | 173 | list_remove_head((&phba->work_list), evtp, typeof(*evtp), |
178 | evt_listp); | 174 | evt_listp); |
179 | spin_unlock_irq(phba->host->host_lock); | 175 | spin_unlock_irq(&phba->hbalock); |
180 | free_evt = 1; | 176 | free_evt = 1; |
181 | switch (evtp->evt) { | 177 | switch (evtp->evt) { |
182 | case LPFC_EVT_ELS_RETRY: | 178 | case LPFC_EVT_ELS_RETRY: |
183 | ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); | 179 | ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1); |
184 | lpfc_els_retry_delay_handler(ndlp); | 180 | lpfc_els_retry_delay_handler(ndlp); |
185 | free_evt = 0; | 181 | free_evt = 0; |
186 | break; | 182 | break; |
187 | case LPFC_EVT_ONLINE: | 183 | case LPFC_EVT_ONLINE: |
188 | if (phba->hba_state < LPFC_LINK_DOWN) | 184 | if (phba->link_state < LPFC_LINK_DOWN) |
189 | *(int *)(evtp->evt_arg1) = lpfc_online(phba); | 185 | *(int *) (evtp->evt_arg1) = lpfc_online(phba); |
190 | else | 186 | else |
191 | *(int *)(evtp->evt_arg1) = 0; | 187 | *(int *) (evtp->evt_arg1) = 0; |
192 | complete((struct completion *)(evtp->evt_arg2)); | 188 | complete((struct completion *)(evtp->evt_arg2)); |
193 | break; | 189 | break; |
194 | case LPFC_EVT_OFFLINE_PREP: | 190 | case LPFC_EVT_OFFLINE_PREP: |
195 | if (phba->hba_state >= LPFC_LINK_DOWN) | 191 | if (phba->link_state >= LPFC_LINK_DOWN) |
196 | lpfc_offline_prep(phba); | 192 | lpfc_offline_prep(phba); |
197 | *(int *)(evtp->evt_arg1) = 0; | 193 | *(int *)(evtp->evt_arg1) = 0; |
198 | complete((struct completion *)(evtp->evt_arg2)); | 194 | complete((struct completion *)(evtp->evt_arg2)); |
@@ -218,33 +214,32 @@ lpfc_work_list_done(struct lpfc_hba * phba) | |||
218 | case LPFC_EVT_KILL: | 214 | case LPFC_EVT_KILL: |
219 | lpfc_offline(phba); | 215 | lpfc_offline(phba); |
220 | *(int *)(evtp->evt_arg1) | 216 | *(int *)(evtp->evt_arg1) |
221 | = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba); | 217 | = (phba->pport->stopped) |
218 | ? 0 : lpfc_sli_brdkill(phba); | ||
222 | lpfc_unblock_mgmt_io(phba); | 219 | lpfc_unblock_mgmt_io(phba); |
223 | complete((struct completion *)(evtp->evt_arg2)); | 220 | complete((struct completion *)(evtp->evt_arg2)); |
224 | break; | 221 | break; |
225 | } | 222 | } |
226 | if (free_evt) | 223 | if (free_evt) |
227 | kfree(evtp); | 224 | kfree(evtp); |
228 | spin_lock_irq(phba->host->host_lock); | 225 | spin_lock_irq(&phba->hbalock); |
229 | } | 226 | } |
230 | spin_unlock_irq(phba->host->host_lock); | 227 | spin_unlock_irq(&phba->hbalock); |
231 | 228 | ||
232 | } | 229 | } |
233 | 230 | ||
234 | static void | 231 | static void |
235 | lpfc_work_done(struct lpfc_hba * phba) | 232 | lpfc_work_done(struct lpfc_hba *phba) |
236 | { | 233 | { |
237 | struct lpfc_sli_ring *pring; | 234 | struct lpfc_sli_ring *pring; |
238 | int i; | 235 | int i; |
239 | uint32_t ha_copy; | 236 | uint32_t ha_copy, control, work_port_events; |
240 | uint32_t control; | 237 | struct lpfc_vport *vport; |
241 | uint32_t work_hba_events; | ||
242 | 238 | ||
243 | spin_lock_irq(phba->host->host_lock); | 239 | spin_lock_irq(&phba->hbalock); |
244 | ha_copy = phba->work_ha; | 240 | ha_copy = phba->work_ha; |
245 | phba->work_ha = 0; | 241 | phba->work_ha = 0; |
246 | work_hba_events=phba->work_hba_events; | 242 | spin_unlock_irq(&phba->hbalock); |
247 | spin_unlock_irq(phba->host->host_lock); | ||
248 | 243 | ||
249 | if (ha_copy & HA_ERATT) | 244 | if (ha_copy & HA_ERATT) |
250 | lpfc_handle_eratt(phba); | 245 | lpfc_handle_eratt(phba); |
@@ -255,21 +250,25 @@ lpfc_work_done(struct lpfc_hba * phba) | |||
255 | if (ha_copy & HA_LATT) | 250 | if (ha_copy & HA_LATT) |
256 | lpfc_handle_latt(phba); | 251 | lpfc_handle_latt(phba); |
257 | 252 | ||
258 | if (work_hba_events & WORKER_DISC_TMO) | 253 | vport = phba->pport; |
259 | lpfc_disc_timeout_handler(phba); | ||
260 | 254 | ||
261 | if (work_hba_events & WORKER_ELS_TMO) | 255 | work_port_events = vport->work_port_events; |
262 | lpfc_els_timeout_handler(phba); | ||
263 | 256 | ||
264 | if (work_hba_events & WORKER_MBOX_TMO) | 257 | if (work_port_events & WORKER_DISC_TMO) |
258 | lpfc_disc_timeout_handler(vport); | ||
259 | |||
260 | if (work_port_events & WORKER_ELS_TMO) | ||
261 | lpfc_els_timeout_handler(vport); | ||
262 | |||
263 | if (work_port_events & WORKER_MBOX_TMO) | ||
265 | lpfc_mbox_timeout_handler(phba); | 264 | lpfc_mbox_timeout_handler(phba); |
266 | 265 | ||
267 | if (work_hba_events & WORKER_FDMI_TMO) | 266 | if (work_port_events & WORKER_FDMI_TMO) |
268 | lpfc_fdmi_tmo_handler(phba); | 267 | lpfc_fdmi_timeout_handler(vport); |
269 | 268 | ||
270 | spin_lock_irq(phba->host->host_lock); | 269 | spin_lock_irq(&phba->hbalock); |
271 | phba->work_hba_events &= ~work_hba_events; | 270 | vport->work_port_events &= ~work_port_events; |
272 | spin_unlock_irq(phba->host->host_lock); | 271 | spin_unlock_irq(&phba->hbalock); |
273 | 272 | ||
274 | for (i = 0; i < phba->sli.num_rings; i++, ha_copy >>= 4) { | 273 | for (i = 0; i < phba->sli.num_rings; i++, ha_copy >>= 4) { |
275 | pring = &phba->sli.ring[i]; | 274 | pring = &phba->sli.ring[i]; |
@@ -286,33 +285,37 @@ lpfc_work_done(struct lpfc_hba * phba) | |||
286 | /* | 285 | /* |
287 | * Turn on Ring interrupts | 286 | * Turn on Ring interrupts |
288 | */ | 287 | */ |
289 | spin_lock_irq(phba->host->host_lock); | 288 | spin_lock_irq(&phba->hbalock); |
290 | control = readl(phba->HCregaddr); | 289 | control = readl(phba->HCregaddr); |
291 | control |= (HC_R0INT_ENA << i); | 290 | control |= (HC_R0INT_ENA << i); |
292 | writel(control, phba->HCregaddr); | 291 | writel(control, phba->HCregaddr); |
293 | readl(phba->HCregaddr); /* flush */ | 292 | readl(phba->HCregaddr); /* flush */ |
294 | spin_unlock_irq(phba->host->host_lock); | 293 | spin_unlock_irq(&phba->hbalock); |
295 | } | 294 | } |
296 | } | 295 | } |
297 | 296 | ||
298 | lpfc_work_list_done (phba); | 297 | lpfc_work_list_done(phba); |
299 | |||
300 | } | 298 | } |
301 | 299 | ||
302 | static int | 300 | static int |
303 | check_work_wait_done(struct lpfc_hba *phba) { | 301 | check_work_wait_done(struct lpfc_hba *phba) |
302 | { | ||
303 | struct lpfc_vport *vport = phba->pport; | ||
304 | int rc = 0; | ||
305 | |||
306 | |||
307 | if (!vport) | ||
308 | return 0; | ||
309 | spin_lock_irq(&phba->hbalock); | ||
304 | 310 | ||
305 | spin_lock_irq(phba->host->host_lock); | ||
306 | if (phba->work_ha || | 311 | if (phba->work_ha || |
307 | phba->work_hba_events || | 312 | vport->work_port_events || |
308 | (!list_empty(&phba->work_list)) || | 313 | (!list_empty(&phba->work_list)) || |
309 | kthread_should_stop()) { | 314 | kthread_should_stop()) |
310 | spin_unlock_irq(phba->host->host_lock); | 315 | rc = 1; |
311 | return 1; | 316 | |
312 | } else { | 317 | spin_unlock_irq(&phba->hbalock); |
313 | spin_unlock_irq(phba->host->host_lock); | 318 | return rc; |
314 | return 0; | ||
315 | } | ||
316 | } | 319 | } |
317 | 320 | ||
318 | int | 321 | int |
@@ -347,7 +350,7 @@ lpfc_do_work(void *p) | |||
347 | * embedding it in the IOCB. | 350 | * embedding it in the IOCB. |
348 | */ | 351 | */ |
349 | int | 352 | int |
350 | lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2, | 353 | lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2, |
351 | uint32_t evt) | 354 | uint32_t evt) |
352 | { | 355 | { |
353 | struct lpfc_work_evt *evtp; | 356 | struct lpfc_work_evt *evtp; |
@@ -364,11 +367,11 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2, | |||
364 | evtp->evt_arg2 = arg2; | 367 | evtp->evt_arg2 = arg2; |
365 | evtp->evt = evt; | 368 | evtp->evt = evt; |
366 | 369 | ||
367 | spin_lock_irq(phba->host->host_lock); | 370 | spin_lock_irq(&phba->hbalock); |
368 | list_add_tail(&evtp->evt_listp, &phba->work_list); | 371 | list_add_tail(&evtp->evt_listp, &phba->work_list); |
369 | if (phba->work_wait) | 372 | if (phba->work_wait) |
370 | wake_up(phba->work_wait); | 373 | wake_up(phba->work_wait); |
371 | spin_unlock_irq(phba->host->host_lock); | 374 | spin_unlock_irq(&phba->hbalock); |
372 | 375 | ||
373 | return 1; | 376 | return 1; |
374 | } | 377 | } |
@@ -376,75 +379,77 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2, | |||
376 | int | 379 | int |
377 | lpfc_linkdown(struct lpfc_hba *phba) | 380 | lpfc_linkdown(struct lpfc_hba *phba) |
378 | { | 381 | { |
379 | struct lpfc_sli *psli; | 382 | struct lpfc_vport *vport = phba->pport; |
383 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
384 | struct lpfc_sli *psli; | ||
380 | struct lpfc_nodelist *ndlp, *next_ndlp; | 385 | struct lpfc_nodelist *ndlp, *next_ndlp; |
381 | LPFC_MBOXQ_t *mb; | 386 | LPFC_MBOXQ_t *mb; |
382 | int rc; | 387 | int rc; |
383 | 388 | ||
384 | psli = &phba->sli; | 389 | psli = &phba->sli; |
385 | /* sysfs or selective reset may call this routine to clean up */ | 390 | if (phba->link_state == LPFC_LINK_DOWN) { |
386 | if (phba->hba_state >= LPFC_LINK_DOWN) { | 391 | return 0; |
387 | if (phba->hba_state == LPFC_LINK_DOWN) | ||
388 | return 0; | ||
389 | |||
390 | spin_lock_irq(phba->host->host_lock); | ||
391 | phba->hba_state = LPFC_LINK_DOWN; | ||
392 | spin_unlock_irq(phba->host->host_lock); | ||
393 | } | 392 | } |
393 | spin_lock_irq(&phba->hbalock); | ||
394 | if (phba->link_state > LPFC_LINK_DOWN) | ||
395 | phba->link_state = LPFC_LINK_DOWN; | ||
396 | spin_unlock_irq(&phba->hbalock); | ||
394 | 397 | ||
395 | fc_host_post_event(phba->host, fc_get_event_number(), | 398 | fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0); |
396 | FCH_EVT_LINKDOWN, 0); | ||
397 | 399 | ||
398 | /* Clean up any firmware default rpi's */ | 400 | /* Clean up any firmware default rpi's */ |
399 | if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { | 401 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
402 | if (mb) { | ||
400 | lpfc_unreg_did(phba, 0xffffffff, mb); | 403 | lpfc_unreg_did(phba, 0xffffffff, mb); |
401 | mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl; | 404 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
402 | if (lpfc_sli_issue_mbox(phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB)) | 405 | if (lpfc_sli_issue_mbox(phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB)) |
403 | == MBX_NOT_FINISHED) { | 406 | == MBX_NOT_FINISHED) { |
404 | mempool_free( mb, phba->mbox_mem_pool); | 407 | mempool_free(mb, phba->mbox_mem_pool); |
405 | } | 408 | } |
406 | } | 409 | } |
407 | 410 | ||
408 | /* Cleanup any outstanding RSCN activity */ | 411 | /* Cleanup any outstanding RSCN activity */ |
409 | lpfc_els_flush_rscn(phba); | 412 | lpfc_els_flush_rscn(vport); |
410 | 413 | ||
411 | /* Cleanup any outstanding ELS commands */ | 414 | /* Cleanup any outstanding ELS commands */ |
412 | lpfc_els_flush_cmd(phba); | 415 | lpfc_els_flush_cmd(vport); |
413 | 416 | ||
414 | /* | 417 | /* |
415 | * Issue a LINK DOWN event to all nodes. | 418 | * Issue a LINK DOWN event to all nodes. |
416 | */ | 419 | */ |
417 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { | 420 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
418 | /* free any ndlp's on unused list */ | 421 | /* free any ndlp's on unused state */ |
419 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 422 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
420 | lpfc_drop_node(phba, ndlp); | 423 | lpfc_drop_node(vport, ndlp); |
421 | else /* otherwise, force node recovery. */ | 424 | else /* otherwise, force node recovery. */ |
422 | rc = lpfc_disc_state_machine(phba, ndlp, NULL, | 425 | rc = lpfc_disc_state_machine(vport, ndlp, NULL, |
423 | NLP_EVT_DEVICE_RECOVERY); | 426 | NLP_EVT_DEVICE_RECOVERY); |
424 | } | 427 | } |
425 | 428 | ||
426 | /* Setup myDID for link up if we are in pt2pt mode */ | 429 | /* Setup myDID for link up if we are in pt2pt mode */ |
427 | if (phba->fc_flag & FC_PT2PT) { | 430 | if (vport->fc_flag & FC_PT2PT) { |
428 | phba->fc_myDID = 0; | 431 | vport->fc_myDID = 0; |
429 | if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { | 432 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
433 | if (mb) { | ||
430 | lpfc_config_link(phba, mb); | 434 | lpfc_config_link(phba, mb); |
431 | mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl; | 435 | mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl; |
432 | if (lpfc_sli_issue_mbox | 436 | if (lpfc_sli_issue_mbox(phba, mb, |
433 | (phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB)) | 437 | (MBX_NOWAIT | MBX_STOP_IOCB)) |
434 | == MBX_NOT_FINISHED) { | 438 | == MBX_NOT_FINISHED) { |
435 | mempool_free( mb, phba->mbox_mem_pool); | 439 | mempool_free(mb, phba->mbox_mem_pool); |
436 | } | 440 | } |
437 | } | 441 | } |
438 | spin_lock_irq(phba->host->host_lock); | 442 | spin_lock_irq(shost->host_lock); |
439 | phba->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI); | 443 | vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI); |
440 | spin_unlock_irq(phba->host->host_lock); | 444 | spin_unlock_irq(shost->host_lock); |
441 | } | 445 | } |
442 | spin_lock_irq(phba->host->host_lock); | 446 | |
443 | phba->fc_flag &= ~FC_LBIT; | 447 | spin_lock_irq(shost->host_lock); |
444 | spin_unlock_irq(phba->host->host_lock); | 448 | vport->fc_flag &= ~FC_LBIT; |
449 | spin_unlock_irq(shost->host_lock); | ||
445 | 450 | ||
446 | /* Turn off discovery timer if its running */ | 451 | /* Turn off discovery timer if its running */ |
447 | lpfc_can_disctmo(phba); | 452 | lpfc_can_disctmo(vport); |
448 | 453 | ||
449 | /* Must process IOCBs on all rings to handle ABORTed I/Os */ | 454 | /* Must process IOCBs on all rings to handle ABORTed I/Os */ |
450 | return 0; | 455 | return 0; |
@@ -453,46 +458,47 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
453 | static int | 458 | static int |
454 | lpfc_linkup(struct lpfc_hba *phba) | 459 | lpfc_linkup(struct lpfc_hba *phba) |
455 | { | 460 | { |
461 | struct lpfc_vport *vport = phba->pport; | ||
462 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
456 | struct lpfc_nodelist *ndlp, *next_ndlp; | 463 | struct lpfc_nodelist *ndlp, *next_ndlp; |
457 | 464 | ||
458 | fc_host_post_event(phba->host, fc_get_event_number(), | 465 | fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKUP, 0); |
459 | FCH_EVT_LINKUP, 0); | ||
460 | 466 | ||
461 | spin_lock_irq(phba->host->host_lock); | 467 | spin_lock_irq(shost->host_lock); |
462 | phba->hba_state = LPFC_LINK_UP; | 468 | phba->link_state = LPFC_LINK_UP; |
463 | phba->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY | | 469 | vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY | |
464 | FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY); | 470 | FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY); |
465 | phba->fc_flag |= FC_NDISC_ACTIVE; | 471 | vport->fc_flag |= FC_NDISC_ACTIVE; |
466 | phba->fc_ns_retry = 0; | 472 | vport->fc_ns_retry = 0; |
467 | spin_unlock_irq(phba->host->host_lock); | 473 | spin_unlock_irq(shost->host_lock); |
468 | 474 | ||
469 | 475 | ||
470 | if (phba->fc_flag & FC_LBIT) { | 476 | if (vport->fc_flag & FC_LBIT) { |
471 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { | 477 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
472 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) { | 478 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) { |
473 | if (ndlp->nlp_type & NLP_FABRIC) { | 479 | if (ndlp->nlp_type & NLP_FABRIC) { |
474 | /* | 480 | /* |
475 | * On Linkup its safe to clean up the | 481 | * On Linkup its safe to clean up the |
476 | * ndlp from Fabric connections. | 482 | * ndlp from Fabric connections. |
477 | */ | 483 | */ |
478 | lpfc_nlp_set_state(phba, ndlp, | 484 | lpfc_nlp_set_state(vport, ndlp, |
479 | NLP_STE_UNUSED_NODE); | 485 | NLP_STE_UNUSED_NODE); |
480 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 486 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { |
481 | /* | 487 | /* |
482 | * Fail outstanding IO now since | 488 | * Fail outstanding IO now since |
483 | * device is marked for PLOGI. | 489 | * device is marked for PLOGI. |
484 | */ | 490 | */ |
485 | lpfc_unreg_rpi(phba, ndlp); | 491 | lpfc_unreg_rpi(vport, ndlp); |
486 | } | 492 | } |
487 | } | 493 | } |
488 | } | 494 | } |
489 | } | 495 | } |
490 | 496 | ||
491 | /* free any ndlp's on unused list */ | 497 | /* free any ndlp's in unused state */ |
492 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, | 498 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, |
493 | nlp_listp) { | 499 | nlp_listp) { |
494 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 500 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
495 | lpfc_drop_node(phba, ndlp); | 501 | lpfc_drop_node(vport, ndlp); |
496 | } | 502 | } |
497 | 503 | ||
498 | return 0; | 504 | return 0; |
@@ -505,14 +511,14 @@ lpfc_linkup(struct lpfc_hba *phba) | |||
505 | * handed off to the SLI layer. | 511 | * handed off to the SLI layer. |
506 | */ | 512 | */ |
507 | void | 513 | void |
508 | lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 514 | lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
509 | { | 515 | { |
510 | struct lpfc_sli *psli; | 516 | struct lpfc_vport *vport = pmb->vport; |
511 | MAILBOX_t *mb; | 517 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
518 | struct lpfc_sli *psli = &phba->sli; | ||
519 | MAILBOX_t *mb = &pmb->mb; | ||
512 | uint32_t control; | 520 | uint32_t control; |
513 | 521 | ||
514 | psli = &phba->sli; | ||
515 | mb = &pmb->mb; | ||
516 | /* Since we don't do discovery right now, turn these off here */ | 522 | /* Since we don't do discovery right now, turn these off here */ |
517 | psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT; | 523 | psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT; |
518 | psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT; | 524 | psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT; |
@@ -520,32 +526,33 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
520 | 526 | ||
521 | /* Check for error */ | 527 | /* Check for error */ |
522 | if ((mb->mbxStatus) && (mb->mbxStatus != 0x1601)) { | 528 | if ((mb->mbxStatus) && (mb->mbxStatus != 0x1601)) { |
523 | /* CLEAR_LA mbox error <mbxStatus> state <hba_state> */ | 529 | /* CLEAR_LA mbox error <mbxStatus> state <port_state> */ |
524 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | 530 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
525 | "%d:0320 CLEAR_LA mbxStatus error x%x hba " | 531 | "%d:0320 CLEAR_LA mbxStatus error x%x hba " |
526 | "state x%x\n", | 532 | "state x%x\n", |
527 | phba->brd_no, mb->mbxStatus, phba->hba_state); | 533 | phba->brd_no, mb->mbxStatus, vport->port_state); |
528 | 534 | ||
529 | phba->hba_state = LPFC_HBA_ERROR; | 535 | phba->link_state = LPFC_HBA_ERROR; |
530 | goto out; | 536 | goto out; |
531 | } | 537 | } |
532 | 538 | ||
533 | if (phba->fc_flag & FC_ABORT_DISCOVERY) | 539 | if (vport->fc_flag & FC_ABORT_DISCOVERY) |
534 | goto out; | 540 | goto out; |
535 | 541 | ||
536 | phba->num_disc_nodes = 0; | 542 | vport->num_disc_nodes = 0; |
537 | /* go thru NPR list and issue ELS PLOGIs */ | 543 | /* go thru NPR nodes and issue ELS PLOGIs */ |
538 | if (phba->fc_npr_cnt) { | 544 | if (vport->fc_npr_cnt) |
539 | lpfc_els_disc_plogi(phba); | 545 | lpfc_els_disc_plogi(vport); |
540 | } | ||
541 | 546 | ||
542 | if (!phba->num_disc_nodes) { | 547 | if (!vport->num_disc_nodes) { |
543 | spin_lock_irq(phba->host->host_lock); | 548 | spin_lock_irq(shost->host_lock); |
544 | phba->fc_flag &= ~FC_NDISC_ACTIVE; | 549 | vport->fc_flag &= ~FC_NDISC_ACTIVE; |
545 | spin_unlock_irq(phba->host->host_lock); | 550 | spin_unlock_irq(shost->host_lock); |
546 | } | 551 | } |
547 | 552 | ||
548 | phba->hba_state = LPFC_HBA_READY; | 553 | printk(KERN_ERR "%s (%d): vport ready\n", |
554 | __FUNCTION__, __LINE__); | ||
555 | vport->port_state = LPFC_VPORT_READY; | ||
549 | 556 | ||
550 | out: | 557 | out: |
551 | /* Device Discovery completes */ | 558 | /* Device Discovery completes */ |
@@ -555,34 +562,34 @@ out: | |||
555 | "%d:0225 Device Discovery completes\n", | 562 | "%d:0225 Device Discovery completes\n", |
556 | phba->brd_no); | 563 | phba->brd_no); |
557 | 564 | ||
558 | mempool_free( pmb, phba->mbox_mem_pool); | 565 | mempool_free(pmb, phba->mbox_mem_pool); |
559 | 566 | ||
560 | spin_lock_irq(phba->host->host_lock); | 567 | spin_lock_irq(shost->host_lock); |
561 | phba->fc_flag &= ~FC_ABORT_DISCOVERY; | 568 | vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK); |
562 | if (phba->fc_flag & FC_ESTABLISH_LINK) { | 569 | spin_unlock_irq(shost->host_lock); |
563 | phba->fc_flag &= ~FC_ESTABLISH_LINK; | ||
564 | } | ||
565 | spin_unlock_irq(phba->host->host_lock); | ||
566 | 570 | ||
567 | del_timer_sync(&phba->fc_estabtmo); | 571 | del_timer_sync(&phba->fc_estabtmo); |
568 | 572 | ||
569 | lpfc_can_disctmo(phba); | 573 | lpfc_can_disctmo(vport); |
570 | 574 | ||
571 | /* turn on Link Attention interrupts */ | 575 | /* turn on Link Attention interrupts */ |
572 | spin_lock_irq(phba->host->host_lock); | 576 | |
577 | spin_lock_irq(&phba->hbalock); | ||
573 | psli->sli_flag |= LPFC_PROCESS_LA; | 578 | psli->sli_flag |= LPFC_PROCESS_LA; |
574 | control = readl(phba->HCregaddr); | 579 | control = readl(phba->HCregaddr); |
575 | control |= HC_LAINT_ENA; | 580 | control |= HC_LAINT_ENA; |
576 | writel(control, phba->HCregaddr); | 581 | writel(control, phba->HCregaddr); |
577 | readl(phba->HCregaddr); /* flush */ | 582 | readl(phba->HCregaddr); /* flush */ |
578 | spin_unlock_irq(phba->host->host_lock); | 583 | spin_unlock_irq(&phba->hbalock); |
579 | 584 | ||
580 | return; | 585 | return; |
581 | } | 586 | } |
582 | 587 | ||
588 | |||
583 | static void | 589 | static void |
584 | lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 590 | lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
585 | { | 591 | { |
592 | struct lpfc_vport *vport = pmb->vport; | ||
586 | struct lpfc_sli *psli = &phba->sli; | 593 | struct lpfc_sli *psli = &phba->sli; |
587 | int rc; | 594 | int rc; |
588 | 595 | ||
@@ -592,58 +599,64 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
592 | mempool_free(pmb, phba->mbox_mem_pool); | 599 | mempool_free(pmb, phba->mbox_mem_pool); |
593 | 600 | ||
594 | if (phba->fc_topology == TOPOLOGY_LOOP && | 601 | if (phba->fc_topology == TOPOLOGY_LOOP && |
595 | phba->fc_flag & FC_PUBLIC_LOOP && | 602 | vport->fc_flag & FC_PUBLIC_LOOP && |
596 | !(phba->fc_flag & FC_LBIT)) { | 603 | !(vport->fc_flag & FC_LBIT)) { |
597 | /* Need to wait for FAN - use discovery timer | 604 | /* Need to wait for FAN - use discovery timer |
598 | * for timeout. hba_state is identically | 605 | * for timeout. port_state is identically |
599 | * LPFC_LOCAL_CFG_LINK while waiting for FAN | 606 | * LPFC_LOCAL_CFG_LINK while waiting for FAN |
600 | */ | 607 | */ |
601 | lpfc_set_disctmo(phba); | 608 | lpfc_set_disctmo(vport); |
602 | return; | 609 | return; |
603 | } | 610 | } |
604 | 611 | ||
605 | /* Start discovery by sending a FLOGI. hba_state is identically | 612 | /* Start discovery by sending a FLOGI. port_state is identically |
606 | * LPFC_FLOGI while waiting for FLOGI cmpl | 613 | * LPFC_FLOGI while waiting for FLOGI cmpl |
607 | */ | 614 | */ |
608 | phba->hba_state = LPFC_FLOGI; | 615 | vport->port_state = LPFC_FLOGI; |
609 | lpfc_set_disctmo(phba); | 616 | lpfc_set_disctmo(vport); |
610 | lpfc_initial_flogi(phba); | 617 | lpfc_initial_flogi(vport); |
611 | return; | 618 | return; |
612 | 619 | ||
613 | out: | 620 | out: |
614 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | 621 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
615 | "%d:0306 CONFIG_LINK mbxStatus error x%x " | 622 | "%d:0306 CONFIG_LINK mbxStatus error x%x " |
616 | "HBA state x%x\n", | 623 | "HBA state x%x\n", |
617 | phba->brd_no, pmb->mb.mbxStatus, phba->hba_state); | 624 | phba->brd_no, pmb->mb.mbxStatus, vport->port_state); |
618 | 625 | ||
619 | lpfc_linkdown(phba); | 626 | lpfc_linkdown(phba); |
620 | 627 | ||
621 | phba->hba_state = LPFC_HBA_ERROR; | 628 | phba->link_state = LPFC_HBA_ERROR; |
622 | 629 | ||
623 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 630 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
624 | "%d:0200 CONFIG_LINK bad hba state x%x\n", | 631 | "%d:0200 CONFIG_LINK bad hba state x%x\n", |
625 | phba->brd_no, phba->hba_state); | 632 | phba->brd_no, vport->port_state); |
626 | 633 | ||
627 | lpfc_clear_la(phba, pmb); | 634 | lpfc_clear_la(phba, pmb); |
635 | printk(KERN_ERR "%s (%d): do clear_la\n", | ||
636 | __FUNCTION__, __LINE__); | ||
628 | pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 637 | pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
638 | pmb->vport = vport; | ||
629 | rc = lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); | 639 | rc = lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); |
630 | if (rc == MBX_NOT_FINISHED) { | 640 | if (rc == MBX_NOT_FINISHED) { |
631 | mempool_free(pmb, phba->mbox_mem_pool); | 641 | mempool_free(pmb, phba->mbox_mem_pool); |
632 | lpfc_disc_flush_list(phba); | 642 | lpfc_disc_flush_list(vport); |
633 | psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 643 | psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
634 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 644 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
635 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 645 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
636 | phba->hba_state = LPFC_HBA_READY; | 646 | printk(KERN_ERR "%s (%d): vport ready\n", |
647 | __FUNCTION__, __LINE__); | ||
648 | vport->port_state = LPFC_VPORT_READY; | ||
637 | } | 649 | } |
638 | return; | 650 | return; |
639 | } | 651 | } |
640 | 652 | ||
641 | static void | 653 | static void |
642 | lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 654 | lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
643 | { | 655 | { |
644 | struct lpfc_sli *psli = &phba->sli; | 656 | struct lpfc_sli *psli = &phba->sli; |
645 | MAILBOX_t *mb = &pmb->mb; | 657 | MAILBOX_t *mb = &pmb->mb; |
646 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; | 658 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; |
659 | struct lpfc_vport *vport = pmb->vport; | ||
647 | 660 | ||
648 | 661 | ||
649 | /* Check for error */ | 662 | /* Check for error */ |
@@ -652,67 +665,78 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
652 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | 665 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
653 | "%d:0319 READ_SPARAM mbxStatus error x%x " | 666 | "%d:0319 READ_SPARAM mbxStatus error x%x " |
654 | "hba state x%x>\n", | 667 | "hba state x%x>\n", |
655 | phba->brd_no, mb->mbxStatus, phba->hba_state); | 668 | phba->brd_no, mb->mbxStatus, vport->port_state); |
656 | 669 | ||
657 | lpfc_linkdown(phba); | 670 | lpfc_linkdown(phba); |
658 | phba->hba_state = LPFC_HBA_ERROR; | 671 | phba->link_state = LPFC_HBA_ERROR; |
659 | goto out; | 672 | goto out; |
660 | } | 673 | } |
661 | 674 | ||
662 | memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt, | 675 | memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt, |
663 | sizeof (struct serv_parm)); | 676 | sizeof (struct serv_parm)); |
664 | if (phba->cfg_soft_wwnn) | 677 | if (phba->cfg_soft_wwnn) |
665 | u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn); | 678 | u64_to_wwn(phba->cfg_soft_wwnn, |
679 | vport->fc_sparam.nodeName.u.wwn); | ||
666 | if (phba->cfg_soft_wwpn) | 680 | if (phba->cfg_soft_wwpn) |
667 | u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn); | 681 | u64_to_wwn(phba->cfg_soft_wwpn, |
668 | memcpy((uint8_t *) & phba->fc_nodename, | 682 | vport->fc_sparam.portName.u.wwn); |
669 | (uint8_t *) & phba->fc_sparam.nodeName, | 683 | memcpy((uint8_t *) &vport->fc_nodename, |
684 | (uint8_t *) &vport->fc_sparam.nodeName, | ||
670 | sizeof (struct lpfc_name)); | 685 | sizeof (struct lpfc_name)); |
671 | memcpy((uint8_t *) & phba->fc_portname, | 686 | memcpy((uint8_t *) &vport->fc_portname, |
672 | (uint8_t *) & phba->fc_sparam.portName, | 687 | (uint8_t *) &vport->fc_sparam.portName, |
673 | sizeof (struct lpfc_name)); | 688 | sizeof (struct lpfc_name)); |
674 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 689 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
675 | kfree(mp); | 690 | kfree(mp); |
676 | mempool_free( pmb, phba->mbox_mem_pool); | 691 | mempool_free(pmb, phba->mbox_mem_pool); |
677 | return; | 692 | return; |
678 | 693 | ||
679 | out: | 694 | out: |
680 | pmb->context1 = NULL; | 695 | pmb->context1 = NULL; |
681 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 696 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
682 | kfree(mp); | 697 | kfree(mp); |
683 | if (phba->hba_state != LPFC_CLEAR_LA) { | 698 | if (phba->link_state != LPFC_CLEAR_LA) { |
699 | struct lpfc_sli_ring *extra_ring = | ||
700 | &psli->ring[psli->extra_ring]; | ||
701 | struct lpfc_sli_ring *fcp_ring = &psli->ring[psli->fcp_ring]; | ||
702 | struct lpfc_sli_ring *next_ring = &psli->ring[psli->next_ring]; | ||
703 | |||
684 | lpfc_clear_la(phba, pmb); | 704 | lpfc_clear_la(phba, pmb); |
705 | printk(KERN_ERR "%s (%d): do clear_la\n", | ||
706 | __FUNCTION__, __LINE__); | ||
685 | pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 707 | pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
708 | pmb->vport = vport; | ||
686 | if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)) | 709 | if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)) |
687 | == MBX_NOT_FINISHED) { | 710 | == MBX_NOT_FINISHED) { |
688 | mempool_free( pmb, phba->mbox_mem_pool); | 711 | mempool_free(pmb, phba->mbox_mem_pool); |
689 | lpfc_disc_flush_list(phba); | 712 | lpfc_disc_flush_list(vport); |
690 | psli->ring[(psli->extra_ring)].flag &= | 713 | extra_ring->flag &= ~LPFC_STOP_IOCB_EVENT; |
691 | ~LPFC_STOP_IOCB_EVENT; | 714 | fcp_ring->flag &= ~LPFC_STOP_IOCB_EVENT; |
692 | psli->ring[(psli->fcp_ring)].flag &= | 715 | next_ring->flag &= ~LPFC_STOP_IOCB_EVENT; |
693 | ~LPFC_STOP_IOCB_EVENT; | 716 | printk(KERN_ERR "%s (%d): vport ready\n", |
694 | psli->ring[(psli->next_ring)].flag &= | 717 | __FUNCTION__, __LINE__); |
695 | ~LPFC_STOP_IOCB_EVENT; | 718 | vport->port_state = LPFC_VPORT_READY; |
696 | phba->hba_state = LPFC_HBA_READY; | ||
697 | } | 719 | } |
698 | } else { | 720 | } else { |
699 | mempool_free( pmb, phba->mbox_mem_pool); | 721 | mempool_free(pmb, phba->mbox_mem_pool); |
700 | } | 722 | } |
701 | return; | 723 | return; |
702 | } | 724 | } |
703 | 725 | ||
704 | static void | 726 | static void |
705 | lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | 727 | lpfc_mbx_process_link_up(struct lpfc_vport *vport, READ_LA_VAR *la) |
706 | { | 728 | { |
707 | int i; | 729 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
730 | struct lpfc_hba *phba = vport->phba; | ||
708 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox; | 731 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox; |
732 | int i; | ||
709 | struct lpfc_dmabuf *mp; | 733 | struct lpfc_dmabuf *mp; |
710 | int rc; | 734 | int rc; |
711 | 735 | ||
712 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 736 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
713 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 737 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
714 | 738 | ||
715 | spin_lock_irq(phba->host->host_lock); | 739 | spin_lock_irq(shost->host_lock); |
716 | switch (la->UlnkSpeed) { | 740 | switch (la->UlnkSpeed) { |
717 | case LA_1GHZ_LINK: | 741 | case LA_1GHZ_LINK: |
718 | phba->fc_linkspeed = LA_1GHZ_LINK; | 742 | phba->fc_linkspeed = LA_1GHZ_LINK; |
@@ -737,9 +761,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
737 | /* Get Loop Map information */ | 761 | /* Get Loop Map information */ |
738 | 762 | ||
739 | if (la->il) | 763 | if (la->il) |
740 | phba->fc_flag |= FC_LBIT; | 764 | vport->fc_flag |= FC_LBIT; |
741 | 765 | ||
742 | phba->fc_myDID = la->granted_AL_PA; | 766 | vport->fc_myDID = la->granted_AL_PA; |
743 | i = la->un.lilpBde64.tus.f.bdeSize; | 767 | i = la->un.lilpBde64.tus.f.bdeSize; |
744 | 768 | ||
745 | if (i == 0) { | 769 | if (i == 0) { |
@@ -781,14 +805,15 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
781 | } | 805 | } |
782 | } | 806 | } |
783 | } else { | 807 | } else { |
784 | phba->fc_myDID = phba->fc_pref_DID; | 808 | vport->fc_myDID = phba->fc_pref_DID; |
785 | phba->fc_flag |= FC_LBIT; | 809 | vport->fc_flag |= FC_LBIT; |
786 | } | 810 | } |
787 | spin_unlock_irq(phba->host->host_lock); | 811 | spin_unlock_irq(shost->host_lock); |
788 | 812 | ||
789 | lpfc_linkup(phba); | 813 | lpfc_linkup(phba); |
790 | if (sparam_mbox) { | 814 | if (sparam_mbox) { |
791 | lpfc_read_sparam(phba, sparam_mbox); | 815 | lpfc_read_sparam(phba, sparam_mbox); |
816 | sparam_mbox->vport = vport; | ||
792 | sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; | 817 | sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; |
793 | rc = lpfc_sli_issue_mbox(phba, sparam_mbox, | 818 | rc = lpfc_sli_issue_mbox(phba, sparam_mbox, |
794 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 819 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
@@ -804,8 +829,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
804 | } | 829 | } |
805 | 830 | ||
806 | if (cfglink_mbox) { | 831 | if (cfglink_mbox) { |
807 | phba->hba_state = LPFC_LOCAL_CFG_LINK; | 832 | vport->port_state = LPFC_LOCAL_CFG_LINK; |
808 | lpfc_config_link(phba, cfglink_mbox); | 833 | lpfc_config_link(phba, cfglink_mbox); |
834 | cfglink_mbox->vport = vport; | ||
809 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; | 835 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; |
810 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, | 836 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, |
811 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 837 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
@@ -815,20 +841,21 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
815 | } | 841 | } |
816 | 842 | ||
817 | static void | 843 | static void |
818 | lpfc_mbx_issue_link_down(struct lpfc_hba *phba) { | 844 | lpfc_mbx_issue_link_down(struct lpfc_hba *phba) |
845 | { | ||
819 | uint32_t control; | 846 | uint32_t control; |
820 | struct lpfc_sli *psli = &phba->sli; | 847 | struct lpfc_sli *psli = &phba->sli; |
821 | 848 | ||
822 | lpfc_linkdown(phba); | 849 | lpfc_linkdown(phba); |
823 | 850 | ||
824 | /* turn on Link Attention interrupts - no CLEAR_LA needed */ | 851 | /* turn on Link Attention interrupts - no CLEAR_LA needed */ |
825 | spin_lock_irq(phba->host->host_lock); | 852 | spin_lock_irq(&phba->hbalock); |
826 | psli->sli_flag |= LPFC_PROCESS_LA; | 853 | psli->sli_flag |= LPFC_PROCESS_LA; |
827 | control = readl(phba->HCregaddr); | 854 | control = readl(phba->HCregaddr); |
828 | control |= HC_LAINT_ENA; | 855 | control |= HC_LAINT_ENA; |
829 | writel(control, phba->HCregaddr); | 856 | writel(control, phba->HCregaddr); |
830 | readl(phba->HCregaddr); /* flush */ | 857 | readl(phba->HCregaddr); /* flush */ |
831 | spin_unlock_irq(phba->host->host_lock); | 858 | spin_unlock_irq(&phba->hbalock); |
832 | } | 859 | } |
833 | 860 | ||
834 | /* | 861 | /* |
@@ -838,8 +865,10 @@ lpfc_mbx_issue_link_down(struct lpfc_hba *phba) { | |||
838 | * handed off to the SLI layer. | 865 | * handed off to the SLI layer. |
839 | */ | 866 | */ |
840 | void | 867 | void |
841 | lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 868 | lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
842 | { | 869 | { |
870 | struct lpfc_vport *vport = pmb->vport; | ||
871 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
843 | READ_LA_VAR *la; | 872 | READ_LA_VAR *la; |
844 | MAILBOX_t *mb = &pmb->mb; | 873 | MAILBOX_t *mb = &pmb->mb; |
845 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 874 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
@@ -851,9 +880,9 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
851 | LOG_LINK_EVENT, | 880 | LOG_LINK_EVENT, |
852 | "%d:1307 READ_LA mbox error x%x state x%x\n", | 881 | "%d:1307 READ_LA mbox error x%x state x%x\n", |
853 | phba->brd_no, | 882 | phba->brd_no, |
854 | mb->mbxStatus, phba->hba_state); | 883 | mb->mbxStatus, vport->port_state); |
855 | lpfc_mbx_issue_link_down(phba); | 884 | lpfc_mbx_issue_link_down(phba); |
856 | phba->hba_state = LPFC_HBA_ERROR; | 885 | phba->link_state = LPFC_HBA_ERROR; |
857 | goto lpfc_mbx_cmpl_read_la_free_mbuf; | 886 | goto lpfc_mbx_cmpl_read_la_free_mbuf; |
858 | } | 887 | } |
859 | 888 | ||
@@ -861,27 +890,26 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
861 | 890 | ||
862 | memcpy(&phba->alpa_map[0], mp->virt, 128); | 891 | memcpy(&phba->alpa_map[0], mp->virt, 128); |
863 | 892 | ||
864 | spin_lock_irq(phba->host->host_lock); | 893 | spin_lock_irq(shost->host_lock); |
865 | if (la->pb) | 894 | if (la->pb) |
866 | phba->fc_flag |= FC_BYPASSED_MODE; | 895 | vport->fc_flag |= FC_BYPASSED_MODE; |
867 | else | 896 | else |
868 | phba->fc_flag &= ~FC_BYPASSED_MODE; | 897 | vport->fc_flag &= ~FC_BYPASSED_MODE; |
869 | spin_unlock_irq(phba->host->host_lock); | 898 | spin_unlock_irq(shost->host_lock); |
870 | 899 | ||
871 | if (((phba->fc_eventTag + 1) < la->eventTag) || | 900 | if (((phba->fc_eventTag + 1) < la->eventTag) || |
872 | (phba->fc_eventTag == la->eventTag)) { | 901 | (phba->fc_eventTag == la->eventTag)) { |
873 | phba->fc_stat.LinkMultiEvent++; | 902 | phba->fc_stat.LinkMultiEvent++; |
874 | if (la->attType == AT_LINK_UP) { | 903 | if (la->attType == AT_LINK_UP) |
875 | if (phba->fc_eventTag != 0) | 904 | if (phba->fc_eventTag != 0) |
876 | lpfc_linkdown(phba); | 905 | lpfc_linkdown(phba); |
877 | } | 906 | } |
878 | } | ||
879 | 907 | ||
880 | phba->fc_eventTag = la->eventTag; | 908 | phba->fc_eventTag = la->eventTag; |
881 | 909 | ||
882 | if (la->attType == AT_LINK_UP) { | 910 | if (la->attType == AT_LINK_UP) { |
883 | phba->fc_stat.LinkUp++; | 911 | phba->fc_stat.LinkUp++; |
884 | if (phba->fc_flag & FC_LOOPBACK_MODE) { | 912 | if (phba->link_flag & LS_LOOPBACK_MODE) { |
885 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, | 913 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, |
886 | "%d:1306 Link Up Event in loop back mode " | 914 | "%d:1306 Link Up Event in loop back mode " |
887 | "x%x received Data: x%x x%x x%x x%x\n", | 915 | "x%x received Data: x%x x%x x%x x%x\n", |
@@ -896,14 +924,14 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
896 | la->granted_AL_PA, la->UlnkSpeed, | 924 | la->granted_AL_PA, la->UlnkSpeed, |
897 | phba->alpa_map[0]); | 925 | phba->alpa_map[0]); |
898 | } | 926 | } |
899 | lpfc_mbx_process_link_up(phba, la); | 927 | lpfc_mbx_process_link_up(vport, la); |
900 | } else { | 928 | } else { |
901 | phba->fc_stat.LinkDown++; | 929 | phba->fc_stat.LinkDown++; |
902 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | 930 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, |
903 | "%d:1305 Link Down Event x%x received " | 931 | "%d:1305 Link Down Event x%x received " |
904 | "Data: x%x x%x x%x\n", | 932 | "Data: x%x x%x x%x\n", |
905 | phba->brd_no, la->eventTag, phba->fc_eventTag, | 933 | phba->brd_no, la->eventTag, phba->fc_eventTag, |
906 | phba->hba_state, phba->fc_flag); | 934 | phba->pport->port_state, vport->fc_flag); |
907 | lpfc_mbx_issue_link_down(phba); | 935 | lpfc_mbx_issue_link_down(phba); |
908 | } | 936 | } |
909 | 937 | ||
@@ -921,26 +949,20 @@ lpfc_mbx_cmpl_read_la_free_mbuf: | |||
921 | * handed off to the SLI layer. | 949 | * handed off to the SLI layer. |
922 | */ | 950 | */ |
923 | void | 951 | void |
924 | lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 952 | lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
925 | { | 953 | { |
926 | struct lpfc_sli *psli; | 954 | struct lpfc_vport *vport = pmb->vport; |
927 | MAILBOX_t *mb; | 955 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; |
928 | struct lpfc_dmabuf *mp; | 956 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
929 | struct lpfc_nodelist *ndlp; | ||
930 | |||
931 | psli = &phba->sli; | ||
932 | mb = &pmb->mb; | ||
933 | 957 | ||
934 | ndlp = (struct lpfc_nodelist *) pmb->context2; | ||
935 | mp = (struct lpfc_dmabuf *) (pmb->context1); | ||
936 | 958 | ||
937 | pmb->context1 = NULL; | 959 | pmb->context1 = NULL; |
938 | 960 | ||
939 | /* Good status, call state machine */ | 961 | /* Good status, call state machine */ |
940 | lpfc_disc_state_machine(phba, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN); | 962 | lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN); |
941 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 963 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
942 | kfree(mp); | 964 | kfree(mp); |
943 | mempool_free( pmb, phba->mbox_mem_pool); | 965 | mempool_free(pmb, phba->mbox_mem_pool); |
944 | lpfc_nlp_put(ndlp); | 966 | lpfc_nlp_put(ndlp); |
945 | 967 | ||
946 | return; | 968 | return; |
@@ -953,20 +975,13 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
953 | * handed off to the SLI layer. | 975 | * handed off to the SLI layer. |
954 | */ | 976 | */ |
955 | void | 977 | void |
956 | lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 978 | lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
957 | { | 979 | { |
958 | struct lpfc_sli *psli; | 980 | struct lpfc_vport *vport = pmb->vport; |
959 | MAILBOX_t *mb; | 981 | MAILBOX_t *mb = &pmb->mb; |
960 | struct lpfc_dmabuf *mp; | 982 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
961 | struct lpfc_nodelist *ndlp; | 983 | struct lpfc_nodelist *ndlp, *ndlp_fdmi; |
962 | struct lpfc_nodelist *ndlp_fdmi; | ||
963 | |||
964 | |||
965 | psli = &phba->sli; | ||
966 | mb = &pmb->mb; | ||
967 | |||
968 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 984 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
969 | mp = (struct lpfc_dmabuf *) (pmb->context1); | ||
970 | 985 | ||
971 | pmb->context1 = NULL; | 986 | pmb->context1 = NULL; |
972 | pmb->context2 = NULL; | 987 | pmb->context2 = NULL; |
@@ -978,57 +993,59 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
978 | lpfc_nlp_put(ndlp); | 993 | lpfc_nlp_put(ndlp); |
979 | 994 | ||
980 | /* FLOGI failed, so just use loop map to make discovery list */ | 995 | /* FLOGI failed, so just use loop map to make discovery list */ |
981 | lpfc_disc_list_loopmap(phba); | 996 | lpfc_disc_list_loopmap(vport); |
982 | 997 | ||
983 | /* Start discovery */ | 998 | /* Start discovery */ |
984 | lpfc_disc_start(phba); | 999 | lpfc_disc_start(vport); |
985 | return; | 1000 | return; |
986 | } | 1001 | } |
987 | 1002 | ||
988 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1003 | ndlp->nlp_rpi = mb->un.varWords[0]; |
989 | ndlp->nlp_type |= NLP_FABRIC; | 1004 | ndlp->nlp_type |= NLP_FABRIC; |
990 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 1005 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
991 | 1006 | ||
992 | lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */ | 1007 | lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */ |
993 | 1008 | ||
994 | if (phba->hba_state == LPFC_FABRIC_CFG_LINK) { | 1009 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { |
995 | /* This NPort has been assigned an NPort_ID by the fabric as a | 1010 | /* This NPort has been assigned an NPort_ID by the fabric as a |
996 | * result of the completed fabric login. Issue a State Change | 1011 | * result of the completed fabric login. Issue a State Change |
997 | * Registration (SCR) ELS request to the fabric controller | 1012 | * Registration (SCR) ELS request to the fabric controller |
998 | * (SCR_DID) so that this NPort gets RSCN events from the | 1013 | * (SCR_DID) so that this NPort gets RSCN events from the |
999 | * fabric. | 1014 | * fabric. |
1000 | */ | 1015 | */ |
1001 | lpfc_issue_els_scr(phba, SCR_DID, 0); | 1016 | lpfc_issue_els_scr(vport, SCR_DID, 0); |
1002 | 1017 | ||
1003 | ndlp = lpfc_findnode_did(phba, NameServer_DID); | 1018 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
1004 | if (!ndlp) { | 1019 | if (!ndlp) { |
1005 | /* Allocate a new node instance. If the pool is empty, | 1020 | /* Allocate a new node instance. If the pool is empty, |
1006 | * start the discovery process and skip the Nameserver | 1021 | * start the discovery process and skip the Nameserver |
1007 | * login process. This is attempted again later on. | 1022 | * login process. This is attempted again later on. |
1008 | * Otherwise, issue a Port Login (PLOGI) to NameServer. | 1023 | * Otherwise, issue a Port Login (PLOGI) to |
1024 | * the NameServer | ||
1009 | */ | 1025 | */ |
1010 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); | 1026 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
1011 | if (!ndlp) { | 1027 | if (!ndlp) { |
1012 | lpfc_disc_start(phba); | 1028 | lpfc_disc_start(vport); |
1013 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1029 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1014 | kfree(mp); | 1030 | kfree(mp); |
1015 | mempool_free(pmb, phba->mbox_mem_pool); | 1031 | mempool_free(pmb, phba->mbox_mem_pool); |
1016 | return; | 1032 | return; |
1017 | } else { | 1033 | } else { |
1018 | lpfc_nlp_init(phba, ndlp, NameServer_DID); | 1034 | lpfc_nlp_init(vport, ndlp, NameServer_DID); |
1019 | ndlp->nlp_type |= NLP_FABRIC; | 1035 | ndlp->nlp_type |= NLP_FABRIC; |
1020 | } | 1036 | } |
1021 | } | 1037 | } |
1022 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 1038 | |
1023 | lpfc_issue_els_plogi(phba, NameServer_DID, 0); | 1039 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
1040 | lpfc_issue_els_plogi(vport, NameServer_DID, 0); | ||
1024 | if (phba->cfg_fdmi_on) { | 1041 | if (phba->cfg_fdmi_on) { |
1025 | ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, | 1042 | ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, |
1026 | GFP_KERNEL); | 1043 | GFP_KERNEL); |
1027 | if (ndlp_fdmi) { | 1044 | if (ndlp_fdmi) { |
1028 | lpfc_nlp_init(phba, ndlp_fdmi, FDMI_DID); | 1045 | lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); |
1029 | ndlp_fdmi->nlp_type |= NLP_FABRIC; | 1046 | ndlp_fdmi->nlp_type |= NLP_FABRIC; |
1030 | ndlp_fdmi->nlp_state = NLP_STE_PLOGI_ISSUE; | 1047 | ndlp_fdmi->nlp_state = NLP_STE_PLOGI_ISSUE; |
1031 | lpfc_issue_els_plogi(phba, FDMI_DID, 0); | 1048 | lpfc_issue_els_plogi(vport, FDMI_DID, 0); |
1032 | } | 1049 | } |
1033 | } | 1050 | } |
1034 | } | 1051 | } |
@@ -1046,32 +1063,28 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
1046 | * handed off to the SLI layer. | 1063 | * handed off to the SLI layer. |
1047 | */ | 1064 | */ |
1048 | void | 1065 | void |
1049 | lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 1066 | lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
1050 | { | 1067 | { |
1051 | struct lpfc_sli *psli; | 1068 | MAILBOX_t *mb = &pmb->mb; |
1052 | MAILBOX_t *mb; | 1069 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
1053 | struct lpfc_dmabuf *mp; | 1070 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
1054 | struct lpfc_nodelist *ndlp; | 1071 | struct lpfc_vport *vport = pmb->vport; |
1055 | |||
1056 | psli = &phba->sli; | ||
1057 | mb = &pmb->mb; | ||
1058 | |||
1059 | ndlp = (struct lpfc_nodelist *) pmb->context2; | ||
1060 | mp = (struct lpfc_dmabuf *) (pmb->context1); | ||
1061 | 1072 | ||
1062 | if (mb->mbxStatus) { | 1073 | if (mb->mbxStatus) { |
1063 | lpfc_nlp_put(ndlp); | 1074 | lpfc_nlp_put(ndlp); |
1064 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1075 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1065 | kfree(mp); | 1076 | kfree(mp); |
1066 | mempool_free(pmb, phba->mbox_mem_pool); | 1077 | mempool_free(pmb, phba->mbox_mem_pool); |
1067 | lpfc_drop_node(phba, ndlp); | 1078 | lpfc_drop_node(vport, ndlp); |
1068 | 1079 | ||
1069 | /* RegLogin failed, so just use loop map to make discovery | 1080 | /* |
1070 | list */ | 1081 | * RegLogin failed, so just use loop map to make discovery |
1071 | lpfc_disc_list_loopmap(phba); | 1082 | * list |
1083 | */ | ||
1084 | lpfc_disc_list_loopmap(vport); | ||
1072 | 1085 | ||
1073 | /* Start discovery */ | 1086 | /* Start discovery */ |
1074 | lpfc_disc_start(phba); | 1087 | lpfc_disc_start(vport); |
1075 | return; | 1088 | return; |
1076 | } | 1089 | } |
1077 | 1090 | ||
@@ -1079,37 +1092,39 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
1079 | 1092 | ||
1080 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1093 | ndlp->nlp_rpi = mb->un.varWords[0]; |
1081 | ndlp->nlp_type |= NLP_FABRIC; | 1094 | ndlp->nlp_type |= NLP_FABRIC; |
1082 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 1095 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1083 | 1096 | ||
1084 | if (phba->hba_state < LPFC_HBA_READY) { | 1097 | if (vport->port_state < LPFC_VPORT_READY) { |
1085 | /* Link up discovery requires Fabrib registration. */ | 1098 | /* Link up discovery requires Fabric registration. */ |
1086 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RNN_ID); | 1099 | lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RNN_ID); |
1087 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RSNN_NN); | 1100 | lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RSNN_NN); |
1088 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFT_ID); | 1101 | lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RFT_ID); |
1089 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFF_ID); | 1102 | lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RFF_ID); |
1090 | } | 1103 | } |
1091 | 1104 | ||
1092 | phba->fc_ns_retry = 0; | 1105 | vport->fc_ns_retry = 0; |
1093 | /* Good status, issue CT Request to NameServer */ | 1106 | /* Good status, issue CT Request to NameServer */ |
1094 | if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT)) { | 1107 | if (lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT)) { |
1095 | /* Cannot issue NameServer Query, so finish up discovery */ | 1108 | /* Cannot issue NameServer Query, so finish up discovery */ |
1096 | lpfc_disc_start(phba); | 1109 | lpfc_disc_start(vport); |
1097 | } | 1110 | } |
1098 | 1111 | ||
1099 | lpfc_nlp_put(ndlp); | 1112 | lpfc_nlp_put(ndlp); |
1100 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1113 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1101 | kfree(mp); | 1114 | kfree(mp); |
1102 | mempool_free( pmb, phba->mbox_mem_pool); | 1115 | mempool_free(pmb, phba->mbox_mem_pool); |
1103 | 1116 | ||
1104 | return; | 1117 | return; |
1105 | } | 1118 | } |
1106 | 1119 | ||
1107 | static void | 1120 | static void |
1108 | lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 1121 | lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1109 | { | 1122 | { |
1110 | struct fc_rport *rport; | 1123 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1124 | struct fc_rport *rport; | ||
1111 | struct lpfc_rport_data *rdata; | 1125 | struct lpfc_rport_data *rdata; |
1112 | struct fc_rport_identifiers rport_ids; | 1126 | struct fc_rport_identifiers rport_ids; |
1127 | struct lpfc_hba *phba = vport->phba; | ||
1113 | 1128 | ||
1114 | /* Remote port has reappeared. Re-register w/ FC transport */ | 1129 | /* Remote port has reappeared. Re-register w/ FC transport */ |
1115 | rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn); | 1130 | rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn); |
@@ -1128,7 +1143,7 @@ lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
1128 | *(struct lpfc_rport_data **) ndlp->rport->dd_data) { | 1143 | *(struct lpfc_rport_data **) ndlp->rport->dd_data) { |
1129 | lpfc_nlp_put(ndlp); | 1144 | lpfc_nlp_put(ndlp); |
1130 | } | 1145 | } |
1131 | ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids); | 1146 | ndlp->rport = rport = fc_remote_port_add(shost, 0, &rport_ids); |
1132 | if (!rport || !get_device(&rport->dev)) { | 1147 | if (!rport || !get_device(&rport->dev)) { |
1133 | dev_printk(KERN_WARNING, &phba->pcidev->dev, | 1148 | dev_printk(KERN_WARNING, &phba->pcidev->dev, |
1134 | "Warning: fc_remote_port_add failed\n"); | 1149 | "Warning: fc_remote_port_add failed\n"); |
@@ -1159,7 +1174,7 @@ lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
1159 | } | 1174 | } |
1160 | 1175 | ||
1161 | static void | 1176 | static void |
1162 | lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 1177 | lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp) |
1163 | { | 1178 | { |
1164 | struct fc_rport *rport = ndlp->rport; | 1179 | struct fc_rport *rport = ndlp->rport; |
1165 | struct lpfc_rport_data *rdata = rport->dd_data; | 1180 | struct lpfc_rport_data *rdata = rport->dd_data; |
@@ -1177,42 +1192,46 @@ lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
1177 | } | 1192 | } |
1178 | 1193 | ||
1179 | static void | 1194 | static void |
1180 | lpfc_nlp_counters(struct lpfc_hba *phba, int state, int count) | 1195 | lpfc_nlp_counters(struct lpfc_vport *vport, int state, int count) |
1181 | { | 1196 | { |
1182 | spin_lock_irq(phba->host->host_lock); | 1197 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1198 | |||
1199 | spin_lock_irq(shost->host_lock); | ||
1183 | switch (state) { | 1200 | switch (state) { |
1184 | case NLP_STE_UNUSED_NODE: | 1201 | case NLP_STE_UNUSED_NODE: |
1185 | phba->fc_unused_cnt += count; | 1202 | vport->fc_unused_cnt += count; |
1186 | break; | 1203 | break; |
1187 | case NLP_STE_PLOGI_ISSUE: | 1204 | case NLP_STE_PLOGI_ISSUE: |
1188 | phba->fc_plogi_cnt += count; | 1205 | vport->fc_plogi_cnt += count; |
1189 | break; | 1206 | break; |
1190 | case NLP_STE_ADISC_ISSUE: | 1207 | case NLP_STE_ADISC_ISSUE: |
1191 | phba->fc_adisc_cnt += count; | 1208 | vport->fc_adisc_cnt += count; |
1192 | break; | 1209 | break; |
1193 | case NLP_STE_REG_LOGIN_ISSUE: | 1210 | case NLP_STE_REG_LOGIN_ISSUE: |
1194 | phba->fc_reglogin_cnt += count; | 1211 | vport->fc_reglogin_cnt += count; |
1195 | break; | 1212 | break; |
1196 | case NLP_STE_PRLI_ISSUE: | 1213 | case NLP_STE_PRLI_ISSUE: |
1197 | phba->fc_prli_cnt += count; | 1214 | vport->fc_prli_cnt += count; |
1198 | break; | 1215 | break; |
1199 | case NLP_STE_UNMAPPED_NODE: | 1216 | case NLP_STE_UNMAPPED_NODE: |
1200 | phba->fc_unmap_cnt += count; | 1217 | vport->fc_unmap_cnt += count; |
1201 | break; | 1218 | break; |
1202 | case NLP_STE_MAPPED_NODE: | 1219 | case NLP_STE_MAPPED_NODE: |
1203 | phba->fc_map_cnt += count; | 1220 | vport->fc_map_cnt += count; |
1204 | break; | 1221 | break; |
1205 | case NLP_STE_NPR_NODE: | 1222 | case NLP_STE_NPR_NODE: |
1206 | phba->fc_npr_cnt += count; | 1223 | vport->fc_npr_cnt += count; |
1207 | break; | 1224 | break; |
1208 | } | 1225 | } |
1209 | spin_unlock_irq(phba->host->host_lock); | 1226 | spin_unlock_irq(shost->host_lock); |
1210 | } | 1227 | } |
1211 | 1228 | ||
1212 | static void | 1229 | static void |
1213 | lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | 1230 | lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1214 | int old_state, int new_state) | 1231 | int old_state, int new_state) |
1215 | { | 1232 | { |
1233 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1234 | |||
1216 | if (new_state == NLP_STE_UNMAPPED_NODE) { | 1235 | if (new_state == NLP_STE_UNMAPPED_NODE) { |
1217 | ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); | 1236 | ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); |
1218 | ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; | 1237 | ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; |
@@ -1226,19 +1245,19 @@ lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
1226 | /* Transport interface */ | 1245 | /* Transport interface */ |
1227 | if (ndlp->rport && (old_state == NLP_STE_MAPPED_NODE || | 1246 | if (ndlp->rport && (old_state == NLP_STE_MAPPED_NODE || |
1228 | old_state == NLP_STE_UNMAPPED_NODE)) { | 1247 | old_state == NLP_STE_UNMAPPED_NODE)) { |
1229 | phba->nport_event_cnt++; | 1248 | vport->phba->nport_event_cnt++; |
1230 | lpfc_unregister_remote_port(phba, ndlp); | 1249 | lpfc_unregister_remote_port(ndlp); |
1231 | } | 1250 | } |
1232 | 1251 | ||
1233 | if (new_state == NLP_STE_MAPPED_NODE || | 1252 | if (new_state == NLP_STE_MAPPED_NODE || |
1234 | new_state == NLP_STE_UNMAPPED_NODE) { | 1253 | new_state == NLP_STE_UNMAPPED_NODE) { |
1235 | phba->nport_event_cnt++; | 1254 | vport->phba->nport_event_cnt++; |
1236 | /* | 1255 | /* |
1237 | * Tell the fc transport about the port, if we haven't | 1256 | * Tell the fc transport about the port, if we haven't |
1238 | * already. If we have, and it's a scsi entity, be | 1257 | * already. If we have, and it's a scsi entity, be |
1239 | * sure to unblock any attached scsi devices | 1258 | * sure to unblock any attached scsi devices |
1240 | */ | 1259 | */ |
1241 | lpfc_register_remote_port(phba, ndlp); | 1260 | lpfc_register_remote_port(vport, ndlp); |
1242 | } | 1261 | } |
1243 | 1262 | ||
1244 | /* | 1263 | /* |
@@ -1251,10 +1270,10 @@ lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
1251 | (!ndlp->rport || | 1270 | (!ndlp->rport || |
1252 | ndlp->rport->scsi_target_id == -1 || | 1271 | ndlp->rport->scsi_target_id == -1 || |
1253 | ndlp->rport->scsi_target_id >= LPFC_MAX_TARGET)) { | 1272 | ndlp->rport->scsi_target_id >= LPFC_MAX_TARGET)) { |
1254 | spin_lock_irq(phba->host->host_lock); | 1273 | spin_lock_irq(shost->host_lock); |
1255 | ndlp->nlp_flag |= NLP_TGT_NO_SCSIID; | 1274 | ndlp->nlp_flag |= NLP_TGT_NO_SCSIID; |
1256 | spin_unlock_irq(phba->host->host_lock); | 1275 | spin_unlock_irq(shost->host_lock); |
1257 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 1276 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1258 | } | 1277 | } |
1259 | } | 1278 | } |
1260 | 1279 | ||
@@ -1280,61 +1299,67 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state) | |||
1280 | } | 1299 | } |
1281 | 1300 | ||
1282 | void | 1301 | void |
1283 | lpfc_nlp_set_state(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, int state) | 1302 | lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1303 | int state) | ||
1284 | { | 1304 | { |
1305 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1285 | int old_state = ndlp->nlp_state; | 1306 | int old_state = ndlp->nlp_state; |
1286 | char name1[16], name2[16]; | 1307 | char name1[16], name2[16]; |
1287 | 1308 | ||
1288 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | 1309 | lpfc_printf_log(vport->phba, KERN_INFO, LOG_NODE, |
1289 | "%d:0904 NPort state transition x%06x, %s -> %s\n", | 1310 | "%d:0904 NPort state transition x%06x, %s -> %s\n", |
1290 | phba->brd_no, | 1311 | vport->phba->brd_no, |
1291 | ndlp->nlp_DID, | 1312 | ndlp->nlp_DID, |
1292 | lpfc_nlp_state_name(name1, sizeof(name1), old_state), | 1313 | lpfc_nlp_state_name(name1, sizeof(name1), old_state), |
1293 | lpfc_nlp_state_name(name2, sizeof(name2), state)); | 1314 | lpfc_nlp_state_name(name2, sizeof(name2), state)); |
1294 | if (old_state == NLP_STE_NPR_NODE && | 1315 | if (old_state == NLP_STE_NPR_NODE && |
1295 | (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 && | 1316 | (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 && |
1296 | state != NLP_STE_NPR_NODE) | 1317 | state != NLP_STE_NPR_NODE) |
1297 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1318 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1298 | if (old_state == NLP_STE_UNMAPPED_NODE) { | 1319 | if (old_state == NLP_STE_UNMAPPED_NODE) { |
1299 | ndlp->nlp_flag &= ~NLP_TGT_NO_SCSIID; | 1320 | ndlp->nlp_flag &= ~NLP_TGT_NO_SCSIID; |
1300 | ndlp->nlp_type &= ~NLP_FC_NODE; | 1321 | ndlp->nlp_type &= ~NLP_FC_NODE; |
1301 | } | 1322 | } |
1302 | 1323 | ||
1303 | if (list_empty(&ndlp->nlp_listp)) { | 1324 | if (list_empty(&ndlp->nlp_listp)) { |
1304 | spin_lock_irq(phba->host->host_lock); | 1325 | spin_lock_irq(shost->host_lock); |
1305 | list_add_tail(&ndlp->nlp_listp, &phba->fc_nodes); | 1326 | list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes); |
1306 | spin_unlock_irq(phba->host->host_lock); | 1327 | spin_unlock_irq(shost->host_lock); |
1307 | } else if (old_state) | 1328 | } else if (old_state) |
1308 | lpfc_nlp_counters(phba, old_state, -1); | 1329 | lpfc_nlp_counters(vport, old_state, -1); |
1309 | 1330 | ||
1310 | ndlp->nlp_state = state; | 1331 | ndlp->nlp_state = state; |
1311 | lpfc_nlp_counters(phba, state, 1); | 1332 | lpfc_nlp_counters(vport, state, 1); |
1312 | lpfc_nlp_state_cleanup(phba, ndlp, old_state, state); | 1333 | lpfc_nlp_state_cleanup(vport, ndlp, old_state, state); |
1313 | } | 1334 | } |
1314 | 1335 | ||
1315 | void | 1336 | void |
1316 | lpfc_dequeue_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 1337 | lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1317 | { | 1338 | { |
1339 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1340 | |||
1318 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) | 1341 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) |
1319 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1342 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1320 | if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) | 1343 | if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) |
1321 | lpfc_nlp_counters(phba, ndlp->nlp_state, -1); | 1344 | lpfc_nlp_counters(vport, ndlp->nlp_state, -1); |
1322 | spin_lock_irq(phba->host->host_lock); | 1345 | spin_lock_irq(shost->host_lock); |
1323 | list_del_init(&ndlp->nlp_listp); | 1346 | list_del_init(&ndlp->nlp_listp); |
1324 | spin_unlock_irq(phba->host->host_lock); | 1347 | spin_unlock_irq(shost->host_lock); |
1325 | lpfc_nlp_state_cleanup(phba, ndlp, ndlp->nlp_state, 0); | 1348 | lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state, 0); |
1326 | } | 1349 | } |
1327 | 1350 | ||
1328 | void | 1351 | void |
1329 | lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 1352 | lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1330 | { | 1353 | { |
1354 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1355 | |||
1331 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) | 1356 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) |
1332 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1357 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1333 | if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) | 1358 | if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) |
1334 | lpfc_nlp_counters(phba, ndlp->nlp_state, -1); | 1359 | lpfc_nlp_counters(vport, ndlp->nlp_state, -1); |
1335 | spin_lock_irq(phba->host->host_lock); | 1360 | spin_lock_irq(shost->host_lock); |
1336 | list_del_init(&ndlp->nlp_listp); | 1361 | list_del_init(&ndlp->nlp_listp); |
1337 | spin_unlock_irq(phba->host->host_lock); | 1362 | spin_unlock_irq(shost->host_lock); |
1338 | lpfc_nlp_put(ndlp); | 1363 | lpfc_nlp_put(ndlp); |
1339 | } | 1364 | } |
1340 | 1365 | ||
@@ -1342,11 +1367,13 @@ lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
1342 | * Start / ReStart rescue timer for Discovery / RSCN handling | 1367 | * Start / ReStart rescue timer for Discovery / RSCN handling |
1343 | */ | 1368 | */ |
1344 | void | 1369 | void |
1345 | lpfc_set_disctmo(struct lpfc_hba * phba) | 1370 | lpfc_set_disctmo(struct lpfc_vport *vport) |
1346 | { | 1371 | { |
1372 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1373 | struct lpfc_hba *phba = vport->phba; | ||
1347 | uint32_t tmo; | 1374 | uint32_t tmo; |
1348 | 1375 | ||
1349 | if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { | 1376 | if (vport->port_state == LPFC_LOCAL_CFG_LINK) { |
1350 | /* For FAN, timeout should be greater then edtov */ | 1377 | /* For FAN, timeout should be greater then edtov */ |
1351 | tmo = (((phba->fc_edtov + 999) / 1000) + 1); | 1378 | tmo = (((phba->fc_edtov + 999) / 1000) + 1); |
1352 | } else { | 1379 | } else { |
@@ -1356,18 +1383,18 @@ lpfc_set_disctmo(struct lpfc_hba * phba) | |||
1356 | tmo = ((phba->fc_ratov * 3) + 3); | 1383 | tmo = ((phba->fc_ratov * 3) + 3); |
1357 | } | 1384 | } |
1358 | 1385 | ||
1359 | mod_timer(&phba->fc_disctmo, jiffies + HZ * tmo); | 1386 | mod_timer(&vport->fc_disctmo, jiffies + HZ * tmo); |
1360 | spin_lock_irq(phba->host->host_lock); | 1387 | spin_lock_irq(shost->host_lock); |
1361 | phba->fc_flag |= FC_DISC_TMO; | 1388 | vport->fc_flag |= FC_DISC_TMO; |
1362 | spin_unlock_irq(phba->host->host_lock); | 1389 | spin_unlock_irq(shost->host_lock); |
1363 | 1390 | ||
1364 | /* Start Discovery Timer state <hba_state> */ | 1391 | /* Start Discovery Timer state <hba_state> */ |
1365 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 1392 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
1366 | "%d:0247 Start Discovery Timer state x%x " | 1393 | "%d:0247 Start Discovery Timer state x%x " |
1367 | "Data: x%x x%lx x%x x%x\n", | 1394 | "Data: x%x x%lx x%x x%x\n", |
1368 | phba->brd_no, | 1395 | phba->brd_no, vport->port_state, tmo, |
1369 | phba->hba_state, tmo, (unsigned long)&phba->fc_disctmo, | 1396 | (unsigned long)&vport->fc_disctmo, vport->fc_plogi_cnt, |
1370 | phba->fc_plogi_cnt, phba->fc_adisc_cnt); | 1397 | vport->fc_adisc_cnt); |
1371 | 1398 | ||
1372 | return; | 1399 | return; |
1373 | } | 1400 | } |
@@ -1376,23 +1403,29 @@ lpfc_set_disctmo(struct lpfc_hba * phba) | |||
1376 | * Cancel rescue timer for Discovery / RSCN handling | 1403 | * Cancel rescue timer for Discovery / RSCN handling |
1377 | */ | 1404 | */ |
1378 | int | 1405 | int |
1379 | lpfc_can_disctmo(struct lpfc_hba * phba) | 1406 | lpfc_can_disctmo(struct lpfc_vport *vport) |
1380 | { | 1407 | { |
1408 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1409 | struct lpfc_hba *phba = vport->phba; | ||
1410 | unsigned long iflags; | ||
1411 | |||
1381 | /* Turn off discovery timer if its running */ | 1412 | /* Turn off discovery timer if its running */ |
1382 | if (phba->fc_flag & FC_DISC_TMO) { | 1413 | if (vport->fc_flag & FC_DISC_TMO) { |
1383 | spin_lock_irq(phba->host->host_lock); | 1414 | spin_lock_irqsave(shost->host_lock, iflags); |
1384 | phba->fc_flag &= ~FC_DISC_TMO; | 1415 | vport->fc_flag &= ~FC_DISC_TMO; |
1385 | spin_unlock_irq(phba->host->host_lock); | 1416 | spin_unlock_irqrestore(shost->host_lock, iflags); |
1386 | del_timer_sync(&phba->fc_disctmo); | 1417 | del_timer_sync(&vport->fc_disctmo); |
1387 | phba->work_hba_events &= ~WORKER_DISC_TMO; | 1418 | spin_lock_irqsave(&vport->work_port_lock, iflags); |
1419 | vport->work_port_events &= ~WORKER_DISC_TMO; | ||
1420 | spin_unlock_irqrestore(&vport->work_port_lock, iflags); | ||
1388 | } | 1421 | } |
1389 | 1422 | ||
1390 | /* Cancel Discovery Timer state <hba_state> */ | 1423 | /* Cancel Discovery Timer state <hba_state> */ |
1391 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 1424 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
1392 | "%d:0248 Cancel Discovery Timer state x%x " | 1425 | "%d:0248 Cancel Discovery Timer state x%x " |
1393 | "Data: x%x x%x x%x\n", | 1426 | "Data: x%x x%x x%x\n", |
1394 | phba->brd_no, phba->hba_state, phba->fc_flag, | 1427 | phba->brd_no, vport->port_state, vport->fc_flag, |
1395 | phba->fc_plogi_cnt, phba->fc_adisc_cnt); | 1428 | vport->fc_plogi_cnt, vport->fc_adisc_cnt); |
1396 | 1429 | ||
1397 | return 0; | 1430 | return 0; |
1398 | } | 1431 | } |
@@ -1402,15 +1435,13 @@ lpfc_can_disctmo(struct lpfc_hba * phba) | |||
1402 | * Return true if iocb matches the specified nport | 1435 | * Return true if iocb matches the specified nport |
1403 | */ | 1436 | */ |
1404 | int | 1437 | int |
1405 | lpfc_check_sli_ndlp(struct lpfc_hba * phba, | 1438 | lpfc_check_sli_ndlp(struct lpfc_hba *phba, |
1406 | struct lpfc_sli_ring * pring, | 1439 | struct lpfc_sli_ring *pring, |
1407 | struct lpfc_iocbq * iocb, struct lpfc_nodelist * ndlp) | 1440 | struct lpfc_iocbq *iocb, |
1441 | struct lpfc_nodelist *ndlp) | ||
1408 | { | 1442 | { |
1409 | struct lpfc_sli *psli; | 1443 | struct lpfc_sli *psli = &phba->sli; |
1410 | IOCB_t *icmd; | 1444 | IOCB_t *icmd = &iocb->iocb; |
1411 | |||
1412 | psli = &phba->sli; | ||
1413 | icmd = &iocb->iocb; | ||
1414 | if (pring->ringno == LPFC_ELS_RING) { | 1445 | if (pring->ringno == LPFC_ELS_RING) { |
1415 | switch (icmd->ulpCommand) { | 1446 | switch (icmd->ulpCommand) { |
1416 | case CMD_GEN_REQUEST64_CR: | 1447 | case CMD_GEN_REQUEST64_CR: |
@@ -1445,7 +1476,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, | |||
1445 | * associated with nlp_rpi in the LPFC_NODELIST entry. | 1476 | * associated with nlp_rpi in the LPFC_NODELIST entry. |
1446 | */ | 1477 | */ |
1447 | static int | 1478 | static int |
1448 | lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1479 | lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) |
1449 | { | 1480 | { |
1450 | LIST_HEAD(completions); | 1481 | LIST_HEAD(completions); |
1451 | struct lpfc_sli *psli; | 1482 | struct lpfc_sli *psli; |
@@ -1465,9 +1496,9 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1465 | for (i = 0; i < psli->num_rings; i++) { | 1496 | for (i = 0; i < psli->num_rings; i++) { |
1466 | pring = &psli->ring[i]; | 1497 | pring = &psli->ring[i]; |
1467 | 1498 | ||
1468 | spin_lock_irq(phba->host->host_lock); | 1499 | spin_lock_irq(&phba->hbalock); |
1469 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, | 1500 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, |
1470 | list) { | 1501 | list) { |
1471 | /* | 1502 | /* |
1472 | * Check to see if iocb matches the nport we are | 1503 | * Check to see if iocb matches the nport we are |
1473 | * looking for | 1504 | * looking for |
@@ -1481,8 +1512,7 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1481 | pring->txq_cnt--; | 1512 | pring->txq_cnt--; |
1482 | } | 1513 | } |
1483 | } | 1514 | } |
1484 | spin_unlock_irq(phba->host->host_lock); | 1515 | spin_unlock_irq(&phba->hbalock); |
1485 | |||
1486 | } | 1516 | } |
1487 | } | 1517 | } |
1488 | 1518 | ||
@@ -1490,13 +1520,14 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1490 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | 1520 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); |
1491 | list_del(&iocb->list); | 1521 | list_del(&iocb->list); |
1492 | 1522 | ||
1493 | if (iocb->iocb_cmpl) { | 1523 | if (!iocb->iocb_cmpl) |
1524 | lpfc_sli_release_iocbq(phba, iocb); | ||
1525 | else { | ||
1494 | icmd = &iocb->iocb; | 1526 | icmd = &iocb->iocb; |
1495 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 1527 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
1496 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | 1528 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
1497 | (iocb->iocb_cmpl) (phba, iocb, iocb); | 1529 | (iocb->iocb_cmpl)(phba, iocb, iocb); |
1498 | } else | 1530 | } |
1499 | lpfc_sli_release_iocbq(phba, iocb); | ||
1500 | } | 1531 | } |
1501 | 1532 | ||
1502 | return 0; | 1533 | return 0; |
@@ -1512,19 +1543,21 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1512 | * we are waiting to PLOGI back to the remote NPort. | 1543 | * we are waiting to PLOGI back to the remote NPort. |
1513 | */ | 1544 | */ |
1514 | int | 1545 | int |
1515 | lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1546 | lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1516 | { | 1547 | { |
1517 | LPFC_MBOXQ_t *mbox; | 1548 | struct lpfc_hba *phba = vport->phba; |
1549 | LPFC_MBOXQ_t *mbox; | ||
1518 | int rc; | 1550 | int rc; |
1519 | 1551 | ||
1520 | if (ndlp->nlp_rpi) { | 1552 | if (ndlp->nlp_rpi) { |
1521 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { | 1553 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
1554 | if (mbox) { | ||
1522 | lpfc_unreg_login(phba, ndlp->nlp_rpi, mbox); | 1555 | lpfc_unreg_login(phba, ndlp->nlp_rpi, mbox); |
1523 | mbox->mbox_cmpl=lpfc_sli_def_mbox_cmpl; | 1556 | mbox->mbox_cmpl=lpfc_sli_def_mbox_cmpl; |
1524 | rc = lpfc_sli_issue_mbox | 1557 | rc = lpfc_sli_issue_mbox |
1525 | (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); | 1558 | (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); |
1526 | if (rc == MBX_NOT_FINISHED) | 1559 | if (rc == MBX_NOT_FINISHED) |
1527 | mempool_free( mbox, phba->mbox_mem_pool); | 1560 | mempool_free(mbox, phba->mbox_mem_pool); |
1528 | } | 1561 | } |
1529 | lpfc_no_rpi(phba, ndlp); | 1562 | lpfc_no_rpi(phba, ndlp); |
1530 | ndlp->nlp_rpi = 0; | 1563 | ndlp->nlp_rpi = 0; |
@@ -1538,10 +1571,11 @@ lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1538 | * so it can be freed. | 1571 | * so it can be freed. |
1539 | */ | 1572 | */ |
1540 | static int | 1573 | static int |
1541 | lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1574 | lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1542 | { | 1575 | { |
1543 | LPFC_MBOXQ_t *mb; | 1576 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1544 | LPFC_MBOXQ_t *nextmb; | 1577 | struct lpfc_hba *phba = vport->phba; |
1578 | LPFC_MBOXQ_t *mb, *nextmb; | ||
1545 | struct lpfc_dmabuf *mp; | 1579 | struct lpfc_dmabuf *mp; |
1546 | 1580 | ||
1547 | /* Cleanup node for NPort <nlp_DID> */ | 1581 | /* Cleanup node for NPort <nlp_DID> */ |
@@ -1551,7 +1585,7 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1551 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, | 1585 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, |
1552 | ndlp->nlp_state, ndlp->nlp_rpi); | 1586 | ndlp->nlp_state, ndlp->nlp_rpi); |
1553 | 1587 | ||
1554 | lpfc_dequeue_node(phba, ndlp); | 1588 | lpfc_dequeue_node(vport, ndlp); |
1555 | 1589 | ||
1556 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ | 1590 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ |
1557 | if ((mb = phba->sli.mbox_active)) { | 1591 | if ((mb = phba->sli.mbox_active)) { |
@@ -1562,13 +1596,13 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1562 | } | 1596 | } |
1563 | } | 1597 | } |
1564 | 1598 | ||
1565 | spin_lock_irq(phba->host->host_lock); | 1599 | spin_lock_irq(&phba->hbalock); |
1566 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { | 1600 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { |
1567 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 1601 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && |
1568 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 1602 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
1569 | mp = (struct lpfc_dmabuf *) (mb->context1); | 1603 | mp = (struct lpfc_dmabuf *) (mb->context1); |
1570 | if (mp) { | 1604 | if (mp) { |
1571 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1605 | __lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1572 | kfree(mp); | 1606 | kfree(mp); |
1573 | } | 1607 | } |
1574 | list_del(&mb->list); | 1608 | list_del(&mb->list); |
@@ -1576,12 +1610,12 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1576 | lpfc_nlp_put(ndlp); | 1610 | lpfc_nlp_put(ndlp); |
1577 | } | 1611 | } |
1578 | } | 1612 | } |
1579 | spin_unlock_irq(phba->host->host_lock); | 1613 | spin_unlock_irq(&phba->hbalock); |
1580 | 1614 | ||
1581 | lpfc_els_abort(phba,ndlp); | 1615 | lpfc_els_abort(phba,ndlp); |
1582 | spin_lock_irq(phba->host->host_lock); | 1616 | spin_lock_irq(shost->host_lock); |
1583 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 1617 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; |
1584 | spin_unlock_irq(phba->host->host_lock); | 1618 | spin_unlock_irq(shost->host_lock); |
1585 | 1619 | ||
1586 | ndlp->nlp_last_elscmd = 0; | 1620 | ndlp->nlp_last_elscmd = 0; |
1587 | del_timer_sync(&ndlp->nlp_delayfunc); | 1621 | del_timer_sync(&ndlp->nlp_delayfunc); |
@@ -1589,7 +1623,7 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1589 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | 1623 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) |
1590 | list_del_init(&ndlp->els_retry_evt.evt_listp); | 1624 | list_del_init(&ndlp->els_retry_evt.evt_listp); |
1591 | 1625 | ||
1592 | lpfc_unreg_rpi(phba, ndlp); | 1626 | lpfc_unreg_rpi(vport, ndlp); |
1593 | 1627 | ||
1594 | return 0; | 1628 | return 0; |
1595 | } | 1629 | } |
@@ -1600,17 +1634,22 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1600 | * machine, defer the free till we reach the end of the state machine. | 1634 | * machine, defer the free till we reach the end of the state machine. |
1601 | */ | 1635 | */ |
1602 | static void | 1636 | static void |
1603 | lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 1637 | lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1604 | { | 1638 | { |
1605 | struct lpfc_rport_data *rdata; | 1639 | struct lpfc_rport_data *rdata; |
1606 | 1640 | ||
1607 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 1641 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
1608 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1642 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1609 | } | 1643 | } |
1610 | 1644 | ||
1611 | lpfc_cleanup_node(phba, ndlp); | 1645 | lpfc_cleanup_node(vport, ndlp); |
1612 | 1646 | ||
1613 | if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { | 1647 | /* |
1648 | * We should never get here with a non-NULL ndlp->rport. But | ||
1649 | * if we do, drop the reference to the rport. That seems the | ||
1650 | * intelligent thing to do. | ||
1651 | */ | ||
1652 | if (ndlp->rport && !(vport->load_flag & FC_UNLOADING)) { | ||
1614 | put_device(&ndlp->rport->dev); | 1653 | put_device(&ndlp->rport->dev); |
1615 | rdata = ndlp->rport->dd_data; | 1654 | rdata = ndlp->rport->dd_data; |
1616 | rdata->pnode = NULL; | 1655 | rdata->pnode = NULL; |
@@ -1619,11 +1658,10 @@ lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
1619 | } | 1658 | } |
1620 | 1659 | ||
1621 | static int | 1660 | static int |
1622 | lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) | 1661 | lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1662 | uint32_t did) | ||
1623 | { | 1663 | { |
1624 | D_ID mydid; | 1664 | D_ID mydid, ndlpdid, matchdid; |
1625 | D_ID ndlpdid; | ||
1626 | D_ID matchdid; | ||
1627 | 1665 | ||
1628 | if (did == Bcast_DID) | 1666 | if (did == Bcast_DID) |
1629 | return 0; | 1667 | return 0; |
@@ -1637,7 +1675,7 @@ lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) | |||
1637 | return 1; | 1675 | return 1; |
1638 | 1676 | ||
1639 | /* Next check for area/domain identically equals 0 match */ | 1677 | /* Next check for area/domain identically equals 0 match */ |
1640 | mydid.un.word = phba->fc_myDID; | 1678 | mydid.un.word = vport->fc_myDID; |
1641 | if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) { | 1679 | if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) { |
1642 | return 0; | 1680 | return 0; |
1643 | } | 1681 | } |
@@ -1669,15 +1707,15 @@ lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) | |||
1669 | } | 1707 | } |
1670 | 1708 | ||
1671 | /* Search for a nodelist entry */ | 1709 | /* Search for a nodelist entry */ |
1672 | struct lpfc_nodelist * | 1710 | static struct lpfc_nodelist * |
1673 | lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did) | 1711 | __lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) |
1674 | { | 1712 | { |
1713 | struct lpfc_hba *phba = vport->phba; | ||
1675 | struct lpfc_nodelist *ndlp; | 1714 | struct lpfc_nodelist *ndlp; |
1676 | uint32_t data1; | 1715 | uint32_t data1; |
1677 | 1716 | ||
1678 | spin_lock_irq(phba->host->host_lock); | 1717 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
1679 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { | 1718 | if (lpfc_matchdid(vport, ndlp, did)) { |
1680 | if (lpfc_matchdid(phba, ndlp, did)) { | ||
1681 | data1 = (((uint32_t) ndlp->nlp_state << 24) | | 1719 | data1 = (((uint32_t) ndlp->nlp_state << 24) | |
1682 | ((uint32_t) ndlp->nlp_xri << 16) | | 1720 | ((uint32_t) ndlp->nlp_xri << 16) | |
1683 | ((uint32_t) ndlp->nlp_type << 8) | | 1721 | ((uint32_t) ndlp->nlp_type << 8) | |
@@ -1688,11 +1726,9 @@ lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did) | |||
1688 | phba->brd_no, | 1726 | phba->brd_no, |
1689 | ndlp, ndlp->nlp_DID, | 1727 | ndlp, ndlp->nlp_DID, |
1690 | ndlp->nlp_flag, data1); | 1728 | ndlp->nlp_flag, data1); |
1691 | spin_unlock_irq(phba->host->host_lock); | ||
1692 | return ndlp; | 1729 | return ndlp; |
1693 | } | 1730 | } |
1694 | } | 1731 | } |
1695 | spin_unlock_irq(phba->host->host_lock); | ||
1696 | 1732 | ||
1697 | /* FIND node did <did> NOT FOUND */ | 1733 | /* FIND node did <did> NOT FOUND */ |
1698 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | 1734 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, |
@@ -1702,68 +1738,85 @@ lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did) | |||
1702 | } | 1738 | } |
1703 | 1739 | ||
1704 | struct lpfc_nodelist * | 1740 | struct lpfc_nodelist * |
1705 | lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) | 1741 | lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) |
1742 | { | ||
1743 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1744 | struct lpfc_nodelist *ndlp; | ||
1745 | |||
1746 | spin_lock_irq(shost->host_lock); | ||
1747 | ndlp = __lpfc_findnode_did(vport, did); | ||
1748 | spin_unlock_irq(shost->host_lock); | ||
1749 | return ndlp; | ||
1750 | } | ||
1751 | |||
1752 | struct lpfc_nodelist * | ||
1753 | lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | ||
1706 | { | 1754 | { |
1755 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1707 | struct lpfc_nodelist *ndlp; | 1756 | struct lpfc_nodelist *ndlp; |
1708 | 1757 | ||
1709 | ndlp = lpfc_findnode_did(phba, did); | 1758 | ndlp = lpfc_findnode_did(vport, did); |
1710 | if (!ndlp) { | 1759 | if (!ndlp) { |
1711 | if ((phba->fc_flag & FC_RSCN_MODE) && | 1760 | if ((vport->fc_flag & FC_RSCN_MODE) != 0 && |
1712 | ((lpfc_rscn_payload_check(phba, did) == 0))) | 1761 | lpfc_rscn_payload_check(vport, did) == 0) |
1713 | return NULL; | 1762 | return NULL; |
1714 | ndlp = (struct lpfc_nodelist *) | 1763 | ndlp = (struct lpfc_nodelist *) |
1715 | mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | 1764 | mempool_alloc(vport->phba->nlp_mem_pool, GFP_KERNEL); |
1716 | if (!ndlp) | 1765 | if (!ndlp) |
1717 | return NULL; | 1766 | return NULL; |
1718 | lpfc_nlp_init(phba, ndlp, did); | 1767 | lpfc_nlp_init(vport, ndlp, did); |
1719 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1768 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1769 | spin_lock_irq(shost->host_lock); | ||
1720 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1770 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
1771 | spin_unlock_irq(shost->host_lock); | ||
1721 | return ndlp; | 1772 | return ndlp; |
1722 | } | 1773 | } |
1723 | if (phba->fc_flag & FC_RSCN_MODE) { | 1774 | if (vport->fc_flag & FC_RSCN_MODE) { |
1724 | if (lpfc_rscn_payload_check(phba, did)) { | 1775 | if (lpfc_rscn_payload_check(vport, did)) { |
1776 | spin_lock_irq(shost->host_lock); | ||
1725 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1777 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
1778 | spin_unlock_irq(shost->host_lock); | ||
1726 | 1779 | ||
1727 | /* Since this node is marked for discovery, | 1780 | /* Since this node is marked for discovery, |
1728 | * delay timeout is not needed. | 1781 | * delay timeout is not needed. |
1729 | */ | 1782 | */ |
1730 | if (ndlp->nlp_flag & NLP_DELAY_TMO) | 1783 | if (ndlp->nlp_flag & NLP_DELAY_TMO) |
1731 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1784 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1732 | } else | 1785 | } else |
1733 | ndlp = NULL; | 1786 | ndlp = NULL; |
1734 | } else { | 1787 | } else { |
1735 | if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE || | 1788 | if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE || |
1736 | ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) | 1789 | ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) |
1737 | return NULL; | 1790 | return NULL; |
1738 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1791 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1792 | spin_lock_irq(shost->host_lock); | ||
1739 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1793 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
1794 | spin_unlock_irq(shost->host_lock); | ||
1740 | } | 1795 | } |
1741 | return ndlp; | 1796 | return ndlp; |
1742 | } | 1797 | } |
1743 | 1798 | ||
1744 | /* Build a list of nodes to discover based on the loopmap */ | 1799 | /* Build a list of nodes to discover based on the loopmap */ |
1745 | void | 1800 | void |
1746 | lpfc_disc_list_loopmap(struct lpfc_hba * phba) | 1801 | lpfc_disc_list_loopmap(struct lpfc_vport *vport) |
1747 | { | 1802 | { |
1803 | struct lpfc_hba *phba = vport->phba; | ||
1748 | int j; | 1804 | int j; |
1749 | uint32_t alpa, index; | 1805 | uint32_t alpa, index; |
1750 | 1806 | ||
1751 | if (phba->hba_state <= LPFC_LINK_DOWN) { | 1807 | if (!lpfc_is_link_up(phba)) |
1752 | return; | 1808 | return; |
1753 | } | 1809 | |
1754 | if (phba->fc_topology != TOPOLOGY_LOOP) { | 1810 | if (phba->fc_topology != TOPOLOGY_LOOP) |
1755 | return; | 1811 | return; |
1756 | } | ||
1757 | 1812 | ||
1758 | /* Check for loop map present or not */ | 1813 | /* Check for loop map present or not */ |
1759 | if (phba->alpa_map[0]) { | 1814 | if (phba->alpa_map[0]) { |
1760 | for (j = 1; j <= phba->alpa_map[0]; j++) { | 1815 | for (j = 1; j <= phba->alpa_map[0]; j++) { |
1761 | alpa = phba->alpa_map[j]; | 1816 | alpa = phba->alpa_map[j]; |
1762 | 1817 | if (((vport->fc_myDID & 0xff) == alpa) || (alpa == 0)) | |
1763 | if (((phba->fc_myDID & 0xff) == alpa) || (alpa == 0)) { | ||
1764 | continue; | 1818 | continue; |
1765 | } | 1819 | lpfc_setup_disc_node(vport, alpa); |
1766 | lpfc_setup_disc_node(phba, alpa); | ||
1767 | } | 1820 | } |
1768 | } else { | 1821 | } else { |
1769 | /* No alpamap, so try all alpa's */ | 1822 | /* No alpamap, so try all alpa's */ |
@@ -1776,113 +1829,139 @@ lpfc_disc_list_loopmap(struct lpfc_hba * phba) | |||
1776 | else | 1829 | else |
1777 | index = FC_MAXLOOP - j - 1; | 1830 | index = FC_MAXLOOP - j - 1; |
1778 | alpa = lpfcAlpaArray[index]; | 1831 | alpa = lpfcAlpaArray[index]; |
1779 | if ((phba->fc_myDID & 0xff) == alpa) { | 1832 | if ((vport->fc_myDID & 0xff) == alpa) |
1780 | continue; | 1833 | continue; |
1781 | } | 1834 | lpfc_setup_disc_node(vport, alpa); |
1782 | |||
1783 | lpfc_setup_disc_node(phba, alpa); | ||
1784 | } | 1835 | } |
1785 | } | 1836 | } |
1786 | return; | 1837 | return; |
1787 | } | 1838 | } |
1788 | 1839 | ||
1789 | /* Start Link up / RSCN discovery on NPR list */ | ||
1790 | void | 1840 | void |
1791 | lpfc_disc_start(struct lpfc_hba * phba) | 1841 | lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport) |
1792 | { | 1842 | { |
1793 | struct lpfc_sli *psli; | ||
1794 | LPFC_MBOXQ_t *mbox; | 1843 | LPFC_MBOXQ_t *mbox; |
1844 | struct lpfc_sli *psli = &phba->sli; | ||
1845 | struct lpfc_sli_ring *extra_ring = &psli->ring[psli->extra_ring]; | ||
1846 | struct lpfc_sli_ring *fcp_ring = &psli->ring[psli->fcp_ring]; | ||
1847 | struct lpfc_sli_ring *next_ring = &psli->ring[psli->next_ring]; | ||
1848 | int rc; | ||
1849 | |||
1850 | /* Link up discovery */ | ||
1851 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) != NULL) { | ||
1852 | phba->link_state = LPFC_CLEAR_LA; | ||
1853 | lpfc_clear_la(phba, mbox); | ||
1854 | mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | ||
1855 | mbox->vport = vport; | ||
1856 | rc = lpfc_sli_issue_mbox(phba, mbox, (MBX_NOWAIT | | ||
1857 | MBX_STOP_IOCB)); | ||
1858 | if (rc == MBX_NOT_FINISHED) { | ||
1859 | mempool_free(mbox, phba->mbox_mem_pool); | ||
1860 | lpfc_disc_flush_list(vport); | ||
1861 | extra_ring->flag &= ~LPFC_STOP_IOCB_EVENT; | ||
1862 | fcp_ring->flag &= ~LPFC_STOP_IOCB_EVENT; | ||
1863 | next_ring->flag &= ~LPFC_STOP_IOCB_EVENT; | ||
1864 | vport->port_state = LPFC_VPORT_READY; | ||
1865 | } | ||
1866 | } | ||
1867 | } | ||
1868 | |||
1869 | /* Start Link up / RSCN discovery on NPR nodes */ | ||
1870 | void | ||
1871 | lpfc_disc_start(struct lpfc_vport *vport) | ||
1872 | { | ||
1873 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1874 | struct lpfc_hba *phba = vport->phba; | ||
1795 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1875 | struct lpfc_nodelist *ndlp, *next_ndlp; |
1796 | uint32_t num_sent; | 1876 | uint32_t num_sent; |
1797 | uint32_t clear_la_pending; | 1877 | uint32_t clear_la_pending; |
1798 | int did_changed; | 1878 | int did_changed; |
1799 | int rc; | ||
1800 | |||
1801 | psli = &phba->sli; | ||
1802 | 1879 | ||
1803 | if (phba->hba_state <= LPFC_LINK_DOWN) { | 1880 | if (!lpfc_is_link_up(phba)) |
1804 | return; | 1881 | return; |
1805 | } | 1882 | |
1806 | if (phba->hba_state == LPFC_CLEAR_LA) | 1883 | if (phba->link_state == LPFC_CLEAR_LA) |
1807 | clear_la_pending = 1; | 1884 | clear_la_pending = 1; |
1808 | else | 1885 | else |
1809 | clear_la_pending = 0; | 1886 | clear_la_pending = 0; |
1810 | 1887 | ||
1811 | if (phba->hba_state < LPFC_HBA_READY) { | 1888 | if (vport->port_state < LPFC_VPORT_READY) |
1812 | phba->hba_state = LPFC_DISC_AUTH; | 1889 | vport->port_state = LPFC_DISC_AUTH; |
1813 | } | ||
1814 | lpfc_set_disctmo(phba); | ||
1815 | 1890 | ||
1816 | if (phba->fc_prevDID == phba->fc_myDID) { | 1891 | lpfc_set_disctmo(vport); |
1892 | |||
1893 | if (vport->fc_prevDID == vport->fc_myDID) | ||
1817 | did_changed = 0; | 1894 | did_changed = 0; |
1818 | } else { | 1895 | else |
1819 | did_changed = 1; | 1896 | did_changed = 1; |
1820 | } | 1897 | |
1821 | phba->fc_prevDID = phba->fc_myDID; | 1898 | vport->fc_prevDID = vport->fc_myDID; |
1822 | phba->num_disc_nodes = 0; | 1899 | vport->num_disc_nodes = 0; |
1823 | 1900 | ||
1824 | /* Start Discovery state <hba_state> */ | 1901 | /* Start Discovery state <hba_state> */ |
1825 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 1902 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
1826 | "%d:0202 Start Discovery hba state x%x " | 1903 | "%d:0202 Start Discovery hba state x%x " |
1827 | "Data: x%x x%x x%x\n", | 1904 | "Data: x%x x%x x%x\n", |
1828 | phba->brd_no, phba->hba_state, phba->fc_flag, | 1905 | phba->brd_no, vport->port_state, vport->fc_flag, |
1829 | phba->fc_plogi_cnt, phba->fc_adisc_cnt); | 1906 | vport->fc_plogi_cnt, vport->fc_adisc_cnt); |
1830 | 1907 | ||
1831 | /* If our did changed, we MUST do PLOGI */ | 1908 | /* If our did changed, we MUST do PLOGI */ |
1832 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { | 1909 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
1833 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && | 1910 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && |
1834 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && | 1911 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && |
1835 | did_changed) { | 1912 | did_changed) { |
1836 | spin_lock_irq(phba->host->host_lock); | 1913 | spin_lock_irq(shost->host_lock); |
1837 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1914 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1838 | spin_unlock_irq(phba->host->host_lock); | 1915 | spin_unlock_irq(shost->host_lock); |
1839 | } | 1916 | } |
1840 | } | 1917 | } |
1841 | 1918 | ||
1842 | /* First do ADISCs - if any */ | 1919 | /* First do ADISCs - if any */ |
1843 | num_sent = lpfc_els_disc_adisc(phba); | 1920 | num_sent = lpfc_els_disc_adisc(vport); |
1844 | 1921 | ||
1845 | if (num_sent) | 1922 | if (num_sent) |
1846 | return; | 1923 | return; |
1847 | 1924 | ||
1848 | if ((phba->hba_state < LPFC_HBA_READY) && (!clear_la_pending)) { | 1925 | if (vport->port_state < LPFC_VPORT_READY && !clear_la_pending) { |
1926 | if (vport->port_type == LPFC_PHYSICAL_PORT) { | ||
1849 | /* If we get here, there is nothing to ADISC */ | 1927 | /* If we get here, there is nothing to ADISC */ |
1850 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { | 1928 | printk(KERN_ERR "%s (%d): do clear_la\n", |
1851 | phba->hba_state = LPFC_CLEAR_LA; | 1929 | __FUNCTION__, __LINE__); |
1852 | lpfc_clear_la(phba, mbox); | 1930 | lpfc_issue_clear_la(phba, vport); |
1853 | mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 1931 | } else if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) { |
1854 | rc = lpfc_sli_issue_mbox(phba, mbox, | 1932 | |
1855 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 1933 | vport->num_disc_nodes = 0; |
1856 | if (rc == MBX_NOT_FINISHED) { | 1934 | /* go thru NPR nodes and issue ELS PLOGIs */ |
1857 | mempool_free( mbox, phba->mbox_mem_pool); | 1935 | if (vport->fc_npr_cnt) |
1858 | lpfc_disc_flush_list(phba); | 1936 | lpfc_els_disc_plogi(vport); |
1859 | psli->ring[(psli->extra_ring)].flag &= | 1937 | |
1860 | ~LPFC_STOP_IOCB_EVENT; | 1938 | if (!vport->num_disc_nodes) { |
1861 | psli->ring[(psli->fcp_ring)].flag &= | 1939 | spin_lock_irq(shost->host_lock); |
1862 | ~LPFC_STOP_IOCB_EVENT; | 1940 | vport->fc_flag &= ~FC_NDISC_ACTIVE; |
1863 | psli->ring[(psli->next_ring)].flag &= | 1941 | spin_unlock_irq(shost->host_lock); |
1864 | ~LPFC_STOP_IOCB_EVENT; | ||
1865 | phba->hba_state = LPFC_HBA_READY; | ||
1866 | } | 1942 | } |
1943 | printk(KERN_ERR "%s (%d): vport ready\n", | ||
1944 | __FUNCTION__, __LINE__); | ||
1945 | vport->port_state = LPFC_VPORT_READY; | ||
1867 | } | 1946 | } |
1868 | } else { | 1947 | } else { |
1869 | /* Next do PLOGIs - if any */ | 1948 | /* Next do PLOGIs - if any */ |
1870 | num_sent = lpfc_els_disc_plogi(phba); | 1949 | num_sent = lpfc_els_disc_plogi(vport); |
1871 | 1950 | ||
1872 | if (num_sent) | 1951 | if (num_sent) |
1873 | return; | 1952 | return; |
1874 | 1953 | ||
1875 | if (phba->fc_flag & FC_RSCN_MODE) { | 1954 | if (vport->fc_flag & FC_RSCN_MODE) { |
1876 | /* Check to see if more RSCNs came in while we | 1955 | /* Check to see if more RSCNs came in while we |
1877 | * were processing this one. | 1956 | * were processing this one. |
1878 | */ | 1957 | */ |
1879 | if ((phba->fc_rscn_id_cnt == 0) && | 1958 | if ((vport->fc_rscn_id_cnt == 0) && |
1880 | (!(phba->fc_flag & FC_RSCN_DISCOVERY))) { | 1959 | (!(vport->fc_flag & FC_RSCN_DISCOVERY))) { |
1881 | spin_lock_irq(phba->host->host_lock); | 1960 | spin_lock_irq(shost->host_lock); |
1882 | phba->fc_flag &= ~FC_RSCN_MODE; | 1961 | vport->fc_flag &= ~FC_RSCN_MODE; |
1883 | spin_unlock_irq(phba->host->host_lock); | 1962 | spin_unlock_irq(shost->host_lock); |
1884 | } else | 1963 | } else |
1885 | lpfc_els_handle_rscn(phba); | 1964 | lpfc_els_handle_rscn(vport); |
1886 | } | 1965 | } |
1887 | } | 1966 | } |
1888 | return; | 1967 | return; |
@@ -1893,7 +1972,7 @@ lpfc_disc_start(struct lpfc_hba * phba) | |||
1893 | * ring the match the sppecified nodelist. | 1972 | * ring the match the sppecified nodelist. |
1894 | */ | 1973 | */ |
1895 | static void | 1974 | static void |
1896 | lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1975 | lpfc_free_tx(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) |
1897 | { | 1976 | { |
1898 | LIST_HEAD(completions); | 1977 | LIST_HEAD(completions); |
1899 | struct lpfc_sli *psli; | 1978 | struct lpfc_sli *psli; |
@@ -1907,7 +1986,7 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1907 | /* Error matching iocb on txq or txcmplq | 1986 | /* Error matching iocb on txq or txcmplq |
1908 | * First check the txq. | 1987 | * First check the txq. |
1909 | */ | 1988 | */ |
1910 | spin_lock_irq(phba->host->host_lock); | 1989 | spin_lock_irq(&phba->hbalock); |
1911 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { | 1990 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { |
1912 | if (iocb->context1 != ndlp) { | 1991 | if (iocb->context1 != ndlp) { |
1913 | continue; | 1992 | continue; |
@@ -1927,36 +2006,36 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1927 | continue; | 2006 | continue; |
1928 | } | 2007 | } |
1929 | icmd = &iocb->iocb; | 2008 | icmd = &iocb->iocb; |
1930 | if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || | 2009 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR || |
1931 | (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { | 2010 | icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX) { |
1932 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); | 2011 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
1933 | } | 2012 | } |
1934 | } | 2013 | } |
1935 | spin_unlock_irq(phba->host->host_lock); | 2014 | spin_unlock_irq(&phba->hbalock); |
1936 | 2015 | ||
1937 | while (!list_empty(&completions)) { | 2016 | while (!list_empty(&completions)) { |
1938 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | 2017 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); |
1939 | list_del(&iocb->list); | 2018 | list_del(&iocb->list); |
1940 | 2019 | ||
1941 | if (iocb->iocb_cmpl) { | 2020 | if (!iocb->iocb_cmpl) |
2021 | lpfc_sli_release_iocbq(phba, iocb); | ||
2022 | else { | ||
1942 | icmd = &iocb->iocb; | 2023 | icmd = &iocb->iocb; |
1943 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 2024 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
1944 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | 2025 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
1945 | (iocb->iocb_cmpl) (phba, iocb, iocb); | 2026 | (iocb->iocb_cmpl) (phba, iocb, iocb); |
1946 | } else | 2027 | } |
1947 | lpfc_sli_release_iocbq(phba, iocb); | ||
1948 | } | 2028 | } |
1949 | |||
1950 | return; | ||
1951 | } | 2029 | } |
1952 | 2030 | ||
1953 | void | 2031 | void |
1954 | lpfc_disc_flush_list(struct lpfc_hba * phba) | 2032 | lpfc_disc_flush_list(struct lpfc_vport *vport) |
1955 | { | 2033 | { |
1956 | struct lpfc_nodelist *ndlp, *next_ndlp; | 2034 | struct lpfc_nodelist *ndlp, *next_ndlp; |
2035 | struct lpfc_hba *phba = vport->phba; | ||
1957 | 2036 | ||
1958 | if (phba->fc_plogi_cnt || phba->fc_adisc_cnt) { | 2037 | if (vport->fc_plogi_cnt || vport->fc_adisc_cnt) { |
1959 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, | 2038 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, |
1960 | nlp_listp) { | 2039 | nlp_listp) { |
1961 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || | 2040 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || |
1962 | ndlp->nlp_state == NLP_STE_ADISC_ISSUE) { | 2041 | ndlp->nlp_state == NLP_STE_ADISC_ISSUE) { |
@@ -1985,47 +2064,51 @@ lpfc_disc_flush_list(struct lpfc_hba * phba) | |||
1985 | void | 2064 | void |
1986 | lpfc_disc_timeout(unsigned long ptr) | 2065 | lpfc_disc_timeout(unsigned long ptr) |
1987 | { | 2066 | { |
1988 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; | 2067 | struct lpfc_vport *vport = (struct lpfc_vport *) ptr; |
2068 | struct lpfc_hba *phba = vport->phba; | ||
1989 | unsigned long flags = 0; | 2069 | unsigned long flags = 0; |
1990 | 2070 | ||
1991 | if (unlikely(!phba)) | 2071 | if (unlikely(!phba)) |
1992 | return; | 2072 | return; |
1993 | 2073 | ||
1994 | spin_lock_irqsave(phba->host->host_lock, flags); | 2074 | if ((vport->work_port_events & WORKER_DISC_TMO) == 0) { |
1995 | if (!(phba->work_hba_events & WORKER_DISC_TMO)) { | 2075 | spin_lock_irqsave(&vport->work_port_lock, flags); |
1996 | phba->work_hba_events |= WORKER_DISC_TMO; | 2076 | vport->work_port_events |= WORKER_DISC_TMO; |
2077 | spin_unlock_irqrestore(&vport->work_port_lock, flags); | ||
2078 | |||
1997 | if (phba->work_wait) | 2079 | if (phba->work_wait) |
1998 | wake_up(phba->work_wait); | 2080 | wake_up(phba->work_wait); |
1999 | } | 2081 | } |
2000 | spin_unlock_irqrestore(phba->host->host_lock, flags); | ||
2001 | return; | 2082 | return; |
2002 | } | 2083 | } |
2003 | 2084 | ||
2004 | static void | 2085 | static void |
2005 | lpfc_disc_timeout_handler(struct lpfc_hba *phba) | 2086 | lpfc_disc_timeout_handler(struct lpfc_vport *vport) |
2006 | { | 2087 | { |
2007 | struct lpfc_sli *psli; | 2088 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
2089 | struct lpfc_hba *phba = vport->phba; | ||
2090 | struct lpfc_sli *psli = &phba->sli; | ||
2008 | struct lpfc_nodelist *ndlp, *next_ndlp; | 2091 | struct lpfc_nodelist *ndlp, *next_ndlp; |
2009 | LPFC_MBOXQ_t *clearlambox, *initlinkmbox; | 2092 | LPFC_MBOXQ_t *clearlambox, *initlinkmbox; |
2010 | int rc, clrlaerr = 0; | 2093 | int rc, clrlaerr = 0; |
2011 | 2094 | ||
2012 | if (unlikely(!phba)) | 2095 | if (!(vport->fc_flag & FC_DISC_TMO)) |
2013 | return; | 2096 | return; |
2014 | 2097 | ||
2015 | if (!(phba->fc_flag & FC_DISC_TMO)) | ||
2016 | return; | ||
2017 | |||
2018 | psli = &phba->sli; | ||
2019 | 2098 | ||
2020 | spin_lock_irq(phba->host->host_lock); | 2099 | spin_lock_irq(shost->host_lock); |
2021 | phba->fc_flag &= ~FC_DISC_TMO; | 2100 | vport->fc_flag &= ~FC_DISC_TMO; |
2022 | spin_unlock_irq(phba->host->host_lock); | 2101 | spin_unlock_irq(shost->host_lock); |
2023 | 2102 | ||
2024 | switch (phba->hba_state) { | 2103 | printk(KERN_ERR "%s (%d): link_state = %d, port_state = %d\n", |
2104 | __FUNCTION__, __LINE__, phba->link_state, vport->port_state); | ||
2105 | switch (vport->port_state) { | ||
2025 | 2106 | ||
2026 | case LPFC_LOCAL_CFG_LINK: | 2107 | case LPFC_LOCAL_CFG_LINK: |
2027 | /* hba_state is identically LPFC_LOCAL_CFG_LINK while waiting for FAN */ | 2108 | /* port_state is identically LPFC_LOCAL_CFG_LINK while waiting for |
2028 | /* FAN timeout */ | 2109 | * FAN |
2110 | */ | ||
2111 | /* FAN timeout */ | ||
2029 | lpfc_printf_log(phba, | 2112 | lpfc_printf_log(phba, |
2030 | KERN_WARNING, | 2113 | KERN_WARNING, |
2031 | LOG_DISCOVERY, | 2114 | LOG_DISCOVERY, |
@@ -2033,27 +2116,27 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2033 | phba->brd_no); | 2116 | phba->brd_no); |
2034 | 2117 | ||
2035 | /* Start discovery by sending FLOGI, clean up old rpis */ | 2118 | /* Start discovery by sending FLOGI, clean up old rpis */ |
2036 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, | 2119 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, |
2037 | nlp_listp) { | 2120 | nlp_listp) { |
2038 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) | 2121 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) |
2039 | continue; | 2122 | continue; |
2040 | if (ndlp->nlp_type & NLP_FABRIC) { | 2123 | if (ndlp->nlp_type & NLP_FABRIC) { |
2041 | /* Clean up the ndlp on Fabric connections */ | 2124 | /* Clean up the ndlp on Fabric connections */ |
2042 | lpfc_drop_node(phba, ndlp); | 2125 | lpfc_drop_node(vport, ndlp); |
2043 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 2126 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { |
2044 | /* Fail outstanding IO now since device | 2127 | /* Fail outstanding IO now since device |
2045 | * is marked for PLOGI. | 2128 | * is marked for PLOGI. |
2046 | */ | 2129 | */ |
2047 | lpfc_unreg_rpi(phba, ndlp); | 2130 | lpfc_unreg_rpi(vport, ndlp); |
2048 | } | 2131 | } |
2049 | } | 2132 | } |
2050 | phba->hba_state = LPFC_FLOGI; | 2133 | vport->port_state = LPFC_FLOGI; |
2051 | lpfc_set_disctmo(phba); | 2134 | lpfc_set_disctmo(vport); |
2052 | lpfc_initial_flogi(phba); | 2135 | lpfc_initial_flogi(vport); |
2053 | break; | 2136 | break; |
2054 | 2137 | ||
2055 | case LPFC_FLOGI: | 2138 | case LPFC_FLOGI: |
2056 | /* hba_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */ | 2139 | /* port_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */ |
2057 | /* Initial FLOGI timeout */ | 2140 | /* Initial FLOGI timeout */ |
2058 | lpfc_printf_log(phba, | 2141 | lpfc_printf_log(phba, |
2059 | KERN_ERR, | 2142 | KERN_ERR, |
@@ -2066,10 +2149,10 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2066 | */ | 2149 | */ |
2067 | 2150 | ||
2068 | /* FLOGI failed, so just use loop map to make discovery list */ | 2151 | /* FLOGI failed, so just use loop map to make discovery list */ |
2069 | lpfc_disc_list_loopmap(phba); | 2152 | lpfc_disc_list_loopmap(vport); |
2070 | 2153 | ||
2071 | /* Start discovery */ | 2154 | /* Start discovery */ |
2072 | lpfc_disc_start(phba); | 2155 | lpfc_disc_start(vport); |
2073 | break; | 2156 | break; |
2074 | 2157 | ||
2075 | case LPFC_FABRIC_CFG_LINK: | 2158 | case LPFC_FABRIC_CFG_LINK: |
@@ -2080,11 +2163,11 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2080 | "login\n", phba->brd_no); | 2163 | "login\n", phba->brd_no); |
2081 | 2164 | ||
2082 | /* Next look for NameServer ndlp */ | 2165 | /* Next look for NameServer ndlp */ |
2083 | ndlp = lpfc_findnode_did(phba, NameServer_DID); | 2166 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
2084 | if (ndlp) | 2167 | if (ndlp) |
2085 | lpfc_nlp_put(ndlp); | 2168 | lpfc_nlp_put(ndlp); |
2086 | /* Start discovery */ | 2169 | /* Start discovery */ |
2087 | lpfc_disc_start(phba); | 2170 | lpfc_disc_start(vport); |
2088 | break; | 2171 | break; |
2089 | 2172 | ||
2090 | case LPFC_NS_QRY: | 2173 | case LPFC_NS_QRY: |
@@ -2093,17 +2176,17 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2093 | "%d:0224 NameServer Query timeout " | 2176 | "%d:0224 NameServer Query timeout " |
2094 | "Data: x%x x%x\n", | 2177 | "Data: x%x x%x\n", |
2095 | phba->brd_no, | 2178 | phba->brd_no, |
2096 | phba->fc_ns_retry, LPFC_MAX_NS_RETRY); | 2179 | vport->fc_ns_retry, LPFC_MAX_NS_RETRY); |
2097 | 2180 | ||
2098 | ndlp = lpfc_findnode_did(phba, NameServer_DID); | 2181 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
2099 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 2182 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { |
2100 | if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) { | 2183 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { |
2101 | /* Try it one more time */ | 2184 | /* Try it one more time */ |
2102 | rc = lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT); | 2185 | rc = lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT); |
2103 | if (rc == 0) | 2186 | if (rc == 0) |
2104 | break; | 2187 | break; |
2105 | } | 2188 | } |
2106 | phba->fc_ns_retry = 0; | 2189 | vport->fc_ns_retry = 0; |
2107 | } | 2190 | } |
2108 | 2191 | ||
2109 | /* Nothing to authenticate, so CLEAR_LA right now */ | 2192 | /* Nothing to authenticate, so CLEAR_LA right now */ |
@@ -2114,13 +2197,16 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2114 | "%d:0226 Device Discovery " | 2197 | "%d:0226 Device Discovery " |
2115 | "completion error\n", | 2198 | "completion error\n", |
2116 | phba->brd_no); | 2199 | phba->brd_no); |
2117 | phba->hba_state = LPFC_HBA_ERROR; | 2200 | phba->link_state = LPFC_HBA_ERROR; |
2118 | break; | 2201 | break; |
2119 | } | 2202 | } |
2120 | 2203 | ||
2121 | phba->hba_state = LPFC_CLEAR_LA; | 2204 | phba->link_state = LPFC_CLEAR_LA; |
2122 | lpfc_clear_la(phba, clearlambox); | 2205 | lpfc_clear_la(phba, clearlambox); |
2206 | printk(KERN_ERR "%s (%d): do clear_la\n", | ||
2207 | __FUNCTION__, __LINE__); | ||
2123 | clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 2208 | clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
2209 | clearlambox->vport = vport; | ||
2124 | rc = lpfc_sli_issue_mbox(phba, clearlambox, | 2210 | rc = lpfc_sli_issue_mbox(phba, clearlambox, |
2125 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 2211 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
2126 | if (rc == MBX_NOT_FINISHED) { | 2212 | if (rc == MBX_NOT_FINISHED) { |
@@ -2136,7 +2222,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2136 | "%d:0206 Device Discovery " | 2222 | "%d:0206 Device Discovery " |
2137 | "completion error\n", | 2223 | "completion error\n", |
2138 | phba->brd_no); | 2224 | phba->brd_no); |
2139 | phba->hba_state = LPFC_HBA_ERROR; | 2225 | phba->link_state = LPFC_HBA_ERROR; |
2140 | break; | 2226 | break; |
2141 | } | 2227 | } |
2142 | 2228 | ||
@@ -2159,7 +2245,8 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2159 | LOG_DISCOVERY, | 2245 | LOG_DISCOVERY, |
2160 | "%d:0227 Node Authentication timeout\n", | 2246 | "%d:0227 Node Authentication timeout\n", |
2161 | phba->brd_no); | 2247 | phba->brd_no); |
2162 | lpfc_disc_flush_list(phba); | 2248 | lpfc_disc_flush_list(vport); |
2249 | |||
2163 | clearlambox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 2250 | clearlambox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
2164 | if (!clearlambox) { | 2251 | if (!clearlambox) { |
2165 | clrlaerr = 1; | 2252 | clrlaerr = 1; |
@@ -2167,12 +2254,15 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2167 | "%d:0207 Device Discovery " | 2254 | "%d:0207 Device Discovery " |
2168 | "completion error\n", | 2255 | "completion error\n", |
2169 | phba->brd_no); | 2256 | phba->brd_no); |
2170 | phba->hba_state = LPFC_HBA_ERROR; | 2257 | phba->link_state = LPFC_HBA_ERROR; |
2171 | break; | 2258 | break; |
2172 | } | 2259 | } |
2173 | phba->hba_state = LPFC_CLEAR_LA; | 2260 | phba->link_state = LPFC_CLEAR_LA; |
2174 | lpfc_clear_la(phba, clearlambox); | 2261 | lpfc_clear_la(phba, clearlambox); |
2262 | printk(KERN_ERR "%s (%d): do clear_la\n", | ||
2263 | __FUNCTION__, __LINE__); | ||
2175 | clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 2264 | clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
2265 | clearlambox->vport = vport; | ||
2176 | rc = lpfc_sli_issue_mbox(phba, clearlambox, | 2266 | rc = lpfc_sli_issue_mbox(phba, clearlambox, |
2177 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 2267 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
2178 | if (rc == MBX_NOT_FINISHED) { | 2268 | if (rc == MBX_NOT_FINISHED) { |
@@ -2181,40 +2271,73 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2181 | } | 2271 | } |
2182 | break; | 2272 | break; |
2183 | 2273 | ||
2184 | case LPFC_CLEAR_LA: | 2274 | case LPFC_VPORT_READY: |
2185 | /* CLEAR LA timeout */ | 2275 | if (vport->fc_flag & FC_RSCN_MODE) { |
2186 | lpfc_printf_log(phba, | ||
2187 | KERN_ERR, | ||
2188 | LOG_DISCOVERY, | ||
2189 | "%d:0228 CLEAR LA timeout\n", | ||
2190 | phba->brd_no); | ||
2191 | clrlaerr = 1; | ||
2192 | break; | ||
2193 | |||
2194 | case LPFC_HBA_READY: | ||
2195 | if (phba->fc_flag & FC_RSCN_MODE) { | ||
2196 | lpfc_printf_log(phba, | 2276 | lpfc_printf_log(phba, |
2197 | KERN_ERR, | 2277 | KERN_ERR, |
2198 | LOG_DISCOVERY, | 2278 | LOG_DISCOVERY, |
2199 | "%d:0231 RSCN timeout Data: x%x x%x\n", | 2279 | "%d:0231 RSCN timeout Data: x%x x%x\n", |
2200 | phba->brd_no, | 2280 | phba->brd_no, |
2201 | phba->fc_ns_retry, LPFC_MAX_NS_RETRY); | 2281 | vport->fc_ns_retry, LPFC_MAX_NS_RETRY); |
2202 | 2282 | ||
2203 | /* Cleanup any outstanding ELS commands */ | 2283 | /* Cleanup any outstanding ELS commands */ |
2204 | lpfc_els_flush_cmd(phba); | 2284 | lpfc_els_flush_cmd(vport); |
2205 | 2285 | ||
2206 | lpfc_els_flush_rscn(phba); | 2286 | lpfc_els_flush_rscn(vport); |
2207 | lpfc_disc_flush_list(phba); | 2287 | lpfc_disc_flush_list(vport); |
2208 | } | 2288 | } |
2209 | break; | 2289 | break; |
2290 | |||
2291 | case LPFC_STATE_UNKNOWN: | ||
2292 | case LPFC_NS_REG: | ||
2293 | case LPFC_BUILD_DISC_LIST: | ||
2294 | lpfc_printf_log(phba, | ||
2295 | KERN_ERR, | ||
2296 | LOG_DISCOVERY, | ||
2297 | "%d:0229 Unexpected discovery timeout, vport " | ||
2298 | "State x%x\n", | ||
2299 | vport->port_state, | ||
2300 | phba->brd_no); | ||
2301 | |||
2302 | break; | ||
2303 | } | ||
2304 | |||
2305 | switch (phba->link_state) { | ||
2306 | case LPFC_CLEAR_LA: | ||
2307 | /* CLEAR LA timeout */ | ||
2308 | lpfc_printf_log(phba, | ||
2309 | KERN_ERR, | ||
2310 | LOG_DISCOVERY, | ||
2311 | "%d:0228 CLEAR LA timeout\n", | ||
2312 | phba->brd_no); | ||
2313 | clrlaerr = 1; | ||
2314 | break; | ||
2315 | |||
2316 | case LPFC_LINK_UNKNOWN: | ||
2317 | case LPFC_WARM_START: | ||
2318 | case LPFC_INIT_START: | ||
2319 | case LPFC_INIT_MBX_CMDS: | ||
2320 | case LPFC_LINK_DOWN: | ||
2321 | case LPFC_LINK_UP: | ||
2322 | case LPFC_HBA_ERROR: | ||
2323 | lpfc_printf_log(phba, | ||
2324 | KERN_ERR, | ||
2325 | LOG_DISCOVERY, | ||
2326 | "%d:0230 Unexpected timeout, hba link " | ||
2327 | "state x%x\n", | ||
2328 | phba->brd_no, phba->link_state); | ||
2329 | clrlaerr = 1; | ||
2330 | break; | ||
2210 | } | 2331 | } |
2211 | 2332 | ||
2212 | if (clrlaerr) { | 2333 | if (clrlaerr) { |
2213 | lpfc_disc_flush_list(phba); | 2334 | lpfc_disc_flush_list(vport); |
2214 | psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 2335 | psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
2215 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 2336 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
2216 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 2337 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
2217 | phba->hba_state = LPFC_HBA_READY; | 2338 | printk(KERN_ERR "%s (%d): vport ready\n", |
2339 | __FUNCTION__, __LINE__); | ||
2340 | vport->port_state = LPFC_VPORT_READY; | ||
2218 | } | 2341 | } |
2219 | 2342 | ||
2220 | return; | 2343 | return; |
@@ -2227,37 +2350,29 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2227 | * handed off to the SLI layer. | 2350 | * handed off to the SLI layer. |
2228 | */ | 2351 | */ |
2229 | void | 2352 | void |
2230 | lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 2353 | lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
2231 | { | 2354 | { |
2232 | struct lpfc_sli *psli; | 2355 | MAILBOX_t *mb = &pmb->mb; |
2233 | MAILBOX_t *mb; | 2356 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
2234 | struct lpfc_dmabuf *mp; | 2357 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
2235 | struct lpfc_nodelist *ndlp; | 2358 | struct lpfc_vport *vport = pmb->vport; |
2236 | |||
2237 | psli = &phba->sli; | ||
2238 | mb = &pmb->mb; | ||
2239 | |||
2240 | ndlp = (struct lpfc_nodelist *) pmb->context2; | ||
2241 | mp = (struct lpfc_dmabuf *) (pmb->context1); | ||
2242 | 2359 | ||
2243 | pmb->context1 = NULL; | 2360 | pmb->context1 = NULL; |
2244 | 2361 | ||
2245 | ndlp->nlp_rpi = mb->un.varWords[0]; | 2362 | ndlp->nlp_rpi = mb->un.varWords[0]; |
2246 | ndlp->nlp_type |= NLP_FABRIC; | 2363 | ndlp->nlp_type |= NLP_FABRIC; |
2247 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 2364 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
2248 | 2365 | ||
2249 | /* Start issuing Fabric-Device Management Interface (FDMI) | 2366 | /* |
2250 | * command to 0xfffffa (FDMI well known port) | 2367 | * Start issuing Fabric-Device Management Interface (FDMI) command to |
2368 | * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if | ||
2369 | * fdmi-on=2 (supporting RPA/hostnmae) | ||
2251 | */ | 2370 | */ |
2252 | if (phba->cfg_fdmi_on == 1) { | 2371 | |
2253 | lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA); | 2372 | if (phba->cfg_fdmi_on == 1) |
2254 | } else { | 2373 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); |
2255 | /* | 2374 | else |
2256 | * Delay issuing FDMI command if fdmi-on=2 | 2375 | mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); |
2257 | * (supporting RPA/hostnmae) | ||
2258 | */ | ||
2259 | mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); | ||
2260 | } | ||
2261 | 2376 | ||
2262 | /* Mailbox took a reference to the node */ | 2377 | /* Mailbox took a reference to the node */ |
2263 | lpfc_nlp_put(ndlp); | 2378 | lpfc_nlp_put(ndlp); |
@@ -2283,16 +2398,12 @@ lpfc_filter_by_wwpn(struct lpfc_nodelist *ndlp, void *param) | |||
2283 | sizeof(ndlp->nlp_portname)) == 0; | 2398 | sizeof(ndlp->nlp_portname)) == 0; |
2284 | } | 2399 | } |
2285 | 2400 | ||
2286 | /* | ||
2287 | * Search node lists for a remote port matching filter criteria | ||
2288 | * Caller needs to hold host_lock before calling this routine. | ||
2289 | */ | ||
2290 | struct lpfc_nodelist * | 2401 | struct lpfc_nodelist * |
2291 | __lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param) | 2402 | __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) |
2292 | { | 2403 | { |
2293 | struct lpfc_nodelist *ndlp; | 2404 | struct lpfc_nodelist *ndlp; |
2294 | 2405 | ||
2295 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { | 2406 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
2296 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE && | 2407 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE && |
2297 | filter(ndlp, param)) | 2408 | filter(ndlp, param)) |
2298 | return ndlp; | 2409 | return ndlp; |
@@ -2305,54 +2416,58 @@ __lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param) | |||
2305 | * This routine is used when the caller does NOT have host_lock. | 2416 | * This routine is used when the caller does NOT have host_lock. |
2306 | */ | 2417 | */ |
2307 | struct lpfc_nodelist * | 2418 | struct lpfc_nodelist * |
2308 | lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param) | 2419 | lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) |
2309 | { | 2420 | { |
2421 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2310 | struct lpfc_nodelist *ndlp; | 2422 | struct lpfc_nodelist *ndlp; |
2311 | 2423 | ||
2312 | spin_lock_irq(phba->host->host_lock); | 2424 | spin_lock_irq(shost->host_lock); |
2313 | ndlp = __lpfc_find_node(phba, filter, param); | 2425 | ndlp = __lpfc_find_node(vport, filter, param); |
2314 | spin_unlock_irq(phba->host->host_lock); | 2426 | spin_unlock_irq(shost->host_lock); |
2315 | return ndlp; | 2427 | return ndlp; |
2316 | } | 2428 | } |
2317 | 2429 | ||
2318 | /* | 2430 | /* |
2319 | * This routine looks up the ndlp lists for the given RPI. If rpi found it | 2431 | * This routine looks up the ndlp lists for the given RPI. If rpi found it |
2320 | * returns the node list pointer else return NULL. | 2432 | * returns the node list element pointer else return NULL. |
2321 | */ | 2433 | */ |
2322 | struct lpfc_nodelist * | 2434 | struct lpfc_nodelist * |
2323 | __lpfc_findnode_rpi(struct lpfc_hba *phba, uint16_t rpi) | 2435 | __lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) |
2324 | { | 2436 | { |
2325 | return __lpfc_find_node(phba, lpfc_filter_by_rpi, &rpi); | 2437 | return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); |
2326 | } | 2438 | } |
2327 | 2439 | ||
2328 | struct lpfc_nodelist * | 2440 | struct lpfc_nodelist * |
2329 | lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) | 2441 | lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) |
2330 | { | 2442 | { |
2443 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2331 | struct lpfc_nodelist *ndlp; | 2444 | struct lpfc_nodelist *ndlp; |
2332 | 2445 | ||
2333 | spin_lock_irq(phba->host->host_lock); | 2446 | spin_lock_irq(shost->host_lock); |
2334 | ndlp = __lpfc_findnode_rpi(phba, rpi); | 2447 | ndlp = __lpfc_findnode_rpi(vport, rpi); |
2335 | spin_unlock_irq(phba->host->host_lock); | 2448 | spin_unlock_irq(shost->host_lock); |
2336 | return ndlp; | 2449 | return ndlp; |
2337 | } | 2450 | } |
2338 | 2451 | ||
2339 | /* | 2452 | /* |
2340 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it | 2453 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it |
2341 | * returns the node list pointer else return NULL. | 2454 | * returns the node element list pointer else return NULL. |
2342 | */ | 2455 | */ |
2343 | struct lpfc_nodelist * | 2456 | struct lpfc_nodelist * |
2344 | lpfc_findnode_wwpn(struct lpfc_hba *phba, struct lpfc_name *wwpn) | 2457 | lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn) |
2345 | { | 2458 | { |
2459 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2346 | struct lpfc_nodelist *ndlp; | 2460 | struct lpfc_nodelist *ndlp; |
2347 | 2461 | ||
2348 | spin_lock_irq(phba->host->host_lock); | 2462 | spin_lock_irq(shost->host_lock); |
2349 | ndlp = __lpfc_find_node(phba, lpfc_filter_by_wwpn, wwpn); | 2463 | ndlp = __lpfc_find_node(vport, lpfc_filter_by_wwpn, wwpn); |
2350 | spin_unlock_irq(phba->host->host_lock); | 2464 | spin_unlock_irq(shost->host_lock); |
2351 | return NULL; | 2465 | return NULL; |
2352 | } | 2466 | } |
2353 | 2467 | ||
2354 | void | 2468 | void |
2355 | lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) | 2469 | lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
2470 | uint32_t did) | ||
2356 | { | 2471 | { |
2357 | memset(ndlp, 0, sizeof (struct lpfc_nodelist)); | 2472 | memset(ndlp, 0, sizeof (struct lpfc_nodelist)); |
2358 | INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); | 2473 | INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); |
@@ -2360,7 +2475,7 @@ lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) | |||
2360 | ndlp->nlp_delayfunc.function = lpfc_els_retry_delay; | 2475 | ndlp->nlp_delayfunc.function = lpfc_els_retry_delay; |
2361 | ndlp->nlp_delayfunc.data = (unsigned long)ndlp; | 2476 | ndlp->nlp_delayfunc.data = (unsigned long)ndlp; |
2362 | ndlp->nlp_DID = did; | 2477 | ndlp->nlp_DID = did; |
2363 | ndlp->nlp_phba = phba; | 2478 | ndlp->vport = vport; |
2364 | ndlp->nlp_sid = NLP_NO_SID; | 2479 | ndlp->nlp_sid = NLP_NO_SID; |
2365 | INIT_LIST_HEAD(&ndlp->nlp_listp); | 2480 | INIT_LIST_HEAD(&ndlp->nlp_listp); |
2366 | kref_init(&ndlp->kref); | 2481 | kref_init(&ndlp->kref); |
@@ -2372,8 +2487,8 @@ lpfc_nlp_release(struct kref *kref) | |||
2372 | { | 2487 | { |
2373 | struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, | 2488 | struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, |
2374 | kref); | 2489 | kref); |
2375 | lpfc_nlp_remove(ndlp->nlp_phba, ndlp); | 2490 | lpfc_nlp_remove(ndlp->vport, ndlp); |
2376 | mempool_free(ndlp, ndlp->nlp_phba->nlp_mem_pool); | 2491 | mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool); |
2377 | } | 2492 | } |
2378 | 2493 | ||
2379 | struct lpfc_nodelist * | 2494 | struct lpfc_nodelist * |