aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c101
1 files changed, 50 insertions, 51 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 110445f0c58d..647f4f3b3748 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -6223,19 +6223,17 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
6223 uint32_t els_command = 0; 6223 uint32_t els_command = 0;
6224 uint32_t timeout; 6224 uint32_t timeout;
6225 uint32_t remote_ID = 0xffffffff; 6225 uint32_t remote_ID = 0xffffffff;
6226 LIST_HEAD(txcmplq_completions);
6227 LIST_HEAD(abort_list); 6226 LIST_HEAD(abort_list);
6228 6227
6229 6228
6230 timeout = (uint32_t)(phba->fc_ratov << 1); 6229 timeout = (uint32_t)(phba->fc_ratov << 1);
6231 6230
6232 pring = &phba->sli.ring[LPFC_ELS_RING]; 6231 pring = &phba->sli.ring[LPFC_ELS_RING];
6233
6234 spin_lock_irq(&phba->hbalock); 6232 spin_lock_irq(&phba->hbalock);
6235 list_splice_init(&pring->txcmplq, &txcmplq_completions); 6233 if (phba->sli_rev == LPFC_SLI_REV4)
6236 spin_unlock_irq(&phba->hbalock); 6234 spin_lock(&pring->ring_lock);
6237 6235
6238 list_for_each_entry_safe(piocb, tmp_iocb, &txcmplq_completions, list) { 6236 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
6239 cmd = &piocb->iocb; 6237 cmd = &piocb->iocb;
6240 6238
6241 if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 || 6239 if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 ||
@@ -6274,8 +6272,8 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
6274 } 6272 }
6275 list_add_tail(&piocb->dlist, &abort_list); 6273 list_add_tail(&piocb->dlist, &abort_list);
6276 } 6274 }
6277 spin_lock_irq(&phba->hbalock); 6275 if (phba->sli_rev == LPFC_SLI_REV4)
6278 list_splice(&txcmplq_completions, &pring->txcmplq); 6276 spin_unlock(&pring->ring_lock);
6279 spin_unlock_irq(&phba->hbalock); 6277 spin_unlock_irq(&phba->hbalock);
6280 6278
6281 list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) { 6279 list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) {
@@ -6317,15 +6315,50 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
6317void 6315void
6318lpfc_els_flush_cmd(struct lpfc_vport *vport) 6316lpfc_els_flush_cmd(struct lpfc_vport *vport)
6319{ 6317{
6320 LIST_HEAD(completions); 6318 LIST_HEAD(abort_list);
6321 struct lpfc_hba *phba = vport->phba; 6319 struct lpfc_hba *phba = vport->phba;
6322 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; 6320 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
6323 struct lpfc_iocbq *tmp_iocb, *piocb; 6321 struct lpfc_iocbq *tmp_iocb, *piocb;
6324 IOCB_t *cmd = NULL; 6322 IOCB_t *cmd = NULL;
6325 6323
6326 lpfc_fabric_abort_vport(vport); 6324 lpfc_fabric_abort_vport(vport);
6325 /*
6326 * For SLI3, only the hbalock is required. But SLI4 needs to coordinate
6327 * with the ring insert operation. Because lpfc_sli_issue_abort_iotag
6328 * ultimately grabs the ring_lock, the driver must splice the list into
6329 * a working list and release the locks before calling the abort.
6330 */
6331 spin_lock_irq(&phba->hbalock);
6332 if (phba->sli_rev == LPFC_SLI_REV4)
6333 spin_lock(&pring->ring_lock);
6334
6335 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
6336 if (piocb->iocb_flag & LPFC_IO_LIBDFC)
6337 continue;
6338
6339 if (piocb->vport != vport)
6340 continue;
6341 list_add_tail(&piocb->dlist, &abort_list);
6342 }
6343 if (phba->sli_rev == LPFC_SLI_REV4)
6344 spin_unlock(&pring->ring_lock);
6345 spin_unlock_irq(&phba->hbalock);
6346 /* Abort each iocb on the aborted list and remove the dlist links. */
6347 list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) {
6348 spin_lock_irq(&phba->hbalock);
6349 list_del_init(&piocb->dlist);
6350 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
6351 spin_unlock_irq(&phba->hbalock);
6352 }
6353 if (!list_empty(&abort_list))
6354 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
6355 "3387 abort list for txq not empty\n");
6356 INIT_LIST_HEAD(&abort_list);
6327 6357
6328 spin_lock_irq(&phba->hbalock); 6358 spin_lock_irq(&phba->hbalock);
6359 if (phba->sli_rev == LPFC_SLI_REV4)
6360 spin_lock(&pring->ring_lock);
6361
6329 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) { 6362 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
6330 cmd = &piocb->iocb; 6363 cmd = &piocb->iocb;
6331 6364
@@ -6343,24 +6376,16 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
6343 if (piocb->vport != vport) 6376 if (piocb->vport != vport)
6344 continue; 6377 continue;
6345 6378
6346 list_move_tail(&piocb->list, &completions); 6379 list_del_init(&piocb->list);
6347 } 6380 list_add_tail(&piocb->list, &abort_list);
6348
6349 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
6350 if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
6351 continue;
6352 }
6353
6354 if (piocb->vport != vport)
6355 continue;
6356
6357 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
6358 } 6381 }
6382 if (phba->sli_rev == LPFC_SLI_REV4)
6383 spin_unlock(&pring->ring_lock);
6359 spin_unlock_irq(&phba->hbalock); 6384 spin_unlock_irq(&phba->hbalock);
6360 6385
6361 /* Cancell all the IOCBs from the completions list */ 6386 /* Cancell all the IOCBs from the completions list */
6362 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, 6387 lpfc_sli_cancel_iocbs(phba, &abort_list,
6363 IOERR_SLI_ABORTED); 6388 IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED);
6364 6389
6365 return; 6390 return;
6366} 6391}
@@ -6385,35 +6410,9 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
6385void 6410void
6386lpfc_els_flush_all_cmd(struct lpfc_hba *phba) 6411lpfc_els_flush_all_cmd(struct lpfc_hba *phba)
6387{ 6412{
6388 LIST_HEAD(completions); 6413 struct lpfc_vport *vport;
6389 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; 6414 list_for_each_entry(vport, &phba->port_list, listentry)
6390 struct lpfc_iocbq *tmp_iocb, *piocb; 6415 lpfc_els_flush_cmd(vport);
6391 IOCB_t *cmd = NULL;
6392
6393 lpfc_fabric_abort_hba(phba);
6394 spin_lock_irq(&phba->hbalock);
6395 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
6396 cmd = &piocb->iocb;
6397 if (piocb->iocb_flag & LPFC_IO_LIBDFC)
6398 continue;
6399 /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */
6400 if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN ||
6401 cmd->ulpCommand == CMD_QUE_RING_BUF64_CN ||
6402 cmd->ulpCommand == CMD_CLOSE_XRI_CN ||
6403 cmd->ulpCommand == CMD_ABORT_XRI_CN)
6404 continue;
6405 list_move_tail(&piocb->list, &completions);
6406 }
6407 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
6408 if (piocb->iocb_flag & LPFC_IO_LIBDFC)
6409 continue;
6410 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
6411 }
6412 spin_unlock_irq(&phba->hbalock);
6413
6414 /* Cancel all the IOCBs from the completions list */
6415 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
6416 IOERR_SLI_ABORTED);
6417 6416
6418 return; 6417 return;
6419} 6418}