aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c72
1 files changed, 26 insertions, 46 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index dcd313ab4a72..16825243e603 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1455,8 +1455,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
1455int 1455int
1456lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) 1456lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
1457{ 1457{
1458 LIST_HEAD(completions);
1458 struct lpfc_iocbq *iocb, *next_iocb; 1459 struct lpfc_iocbq *iocb, *next_iocb;
1459 IOCB_t *icmd = NULL, *cmd = NULL; 1460 IOCB_t *cmd = NULL;
1460 int errcnt; 1461 int errcnt;
1461 1462
1462 errcnt = 0; 1463 errcnt = 0;
@@ -1465,46 +1466,28 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
1465 * First do the txq. 1466 * First do the txq.
1466 */ 1467 */
1467 spin_lock_irq(phba->host->host_lock); 1468 spin_lock_irq(phba->host->host_lock);
1468 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { 1469 list_splice_init(&pring->txq, &completions);
1469 list_del_init(&iocb->list);
1470 if (iocb->iocb_cmpl) {
1471 icmd = &iocb->iocb;
1472 icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
1473 icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
1474 spin_unlock_irq(phba->host->host_lock);
1475 (iocb->iocb_cmpl) (phba, iocb, iocb);
1476 spin_lock_irq(phba->host->host_lock);
1477 } else
1478 lpfc_sli_release_iocbq(phba, iocb);
1479 }
1480 pring->txq_cnt = 0; 1470 pring->txq_cnt = 0;
1481 INIT_LIST_HEAD(&(pring->txq));
1482 1471
1483 /* Next issue ABTS for everything on the txcmplq */ 1472 /* Next issue ABTS for everything on the txcmplq */
1484 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { 1473 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list)
1485 cmd = &iocb->iocb; 1474 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
1486 1475
1487 /* 1476 spin_unlock_irq(phba->host->host_lock);
1488 * Imediate abort of IOCB, deque and call compl
1489 */
1490 1477
1491 list_del_init(&iocb->list); 1478 while (!list_empty(&completions)) {
1492 pring->txcmplq_cnt--; 1479 iocb = list_get_first(&completions, struct lpfc_iocbq, list);
1480 cmd = &iocb->iocb;
1481 list_del(&iocb->list);
1493 1482
1494 if (iocb->iocb_cmpl) { 1483 if (iocb->iocb_cmpl) {
1495 cmd->ulpStatus = IOSTAT_LOCAL_REJECT; 1484 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
1496 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; 1485 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
1497 spin_unlock_irq(phba->host->host_lock);
1498 (iocb->iocb_cmpl) (phba, iocb, iocb); 1486 (iocb->iocb_cmpl) (phba, iocb, iocb);
1499 spin_lock_irq(phba->host->host_lock);
1500 } else 1487 } else
1501 lpfc_sli_release_iocbq(phba, iocb); 1488 lpfc_sli_release_iocbq(phba, iocb);
1502 } 1489 }
1503 1490
1504 INIT_LIST_HEAD(&pring->txcmplq);
1505 pring->txcmplq_cnt = 0;
1506 spin_unlock_irq(phba->host->host_lock);
1507
1508 return errcnt; 1491 return errcnt;
1509} 1492}
1510 1493
@@ -2605,11 +2588,12 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba)
2605int 2588int
2606lpfc_sli_hba_down(struct lpfc_hba * phba) 2589lpfc_sli_hba_down(struct lpfc_hba * phba)
2607{ 2590{
2591 LIST_HEAD(completions);
2608 struct lpfc_sli *psli; 2592 struct lpfc_sli *psli;
2609 struct lpfc_sli_ring *pring; 2593 struct lpfc_sli_ring *pring;
2610 LPFC_MBOXQ_t *pmb; 2594 LPFC_MBOXQ_t *pmb;
2611 struct lpfc_iocbq *iocb, *next_iocb; 2595 struct lpfc_iocbq *iocb;
2612 IOCB_t *icmd = NULL; 2596 IOCB_t *cmd = NULL;
2613 int i; 2597 int i;
2614 unsigned long flags = 0; 2598 unsigned long flags = 0;
2615 2599
@@ -2617,7 +2601,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
2617 lpfc_hba_down_prep(phba); 2601 lpfc_hba_down_prep(phba);
2618 2602
2619 spin_lock_irqsave(phba->host->host_lock, flags); 2603 spin_lock_irqsave(phba->host->host_lock, flags);
2620
2621 for (i = 0; i < psli->num_rings; i++) { 2604 for (i = 0; i < psli->num_rings; i++) {
2622 pring = &psli->ring[i]; 2605 pring = &psli->ring[i];
2623 pring->flag |= LPFC_DEFERRED_RING_EVENT; 2606 pring->flag |= LPFC_DEFERRED_RING_EVENT;
@@ -2626,28 +2609,25 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
2626 * Error everything on the txq since these iocbs have not been 2609 * Error everything on the txq since these iocbs have not been
2627 * given to the FW yet. 2610 * given to the FW yet.
2628 */ 2611 */
2612 list_splice_init(&pring->txq, &completions);
2629 pring->txq_cnt = 0; 2613 pring->txq_cnt = 0;
2630 2614
2631 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { 2615 }
2632 list_del_init(&iocb->list); 2616 spin_unlock_irqrestore(phba->host->host_lock, flags);
2633 if (iocb->iocb_cmpl) {
2634 icmd = &iocb->iocb;
2635 icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
2636 icmd->un.ulpWord[4] = IOERR_SLI_DOWN;
2637 spin_unlock_irqrestore(phba->host->host_lock,
2638 flags);
2639 (iocb->iocb_cmpl) (phba, iocb, iocb);
2640 spin_lock_irqsave(phba->host->host_lock, flags);
2641 } else
2642 lpfc_sli_release_iocbq(phba, iocb);
2643 }
2644 2617
2645 INIT_LIST_HEAD(&(pring->txq)); 2618 while (!list_empty(&completions)) {
2619 iocb = list_get_first(&completions, struct lpfc_iocbq, list);
2620 cmd = &iocb->iocb;
2621 list_del(&iocb->list);
2646 2622
2623 if (iocb->iocb_cmpl) {
2624 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
2625 cmd->un.ulpWord[4] = IOERR_SLI_DOWN;
2626 (iocb->iocb_cmpl) (phba, iocb, iocb);
2627 } else
2628 lpfc_sli_release_iocbq(phba, iocb);
2647 } 2629 }
2648 2630
2649 spin_unlock_irqrestore(phba->host->host_lock, flags);
2650
2651 /* Return any active mbox cmds */ 2631 /* Return any active mbox cmds */
2652 del_timer_sync(&psli->mbox_tmo); 2632 del_timer_sync(&psli->mbox_tmo);
2653 spin_lock_irqsave(phba->host->host_lock, flags); 2633 spin_lock_irqsave(phba->host->host_lock, flags);