diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 427 |
1 files changed, 231 insertions, 196 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 9fb6960a8ada..a1e721459e2b 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -528,6 +528,7 @@ lpfc_sli_wake_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) | |||
528 | * If pdone_q is empty, the driver thread gave up waiting and | 528 | * If pdone_q is empty, the driver thread gave up waiting and |
529 | * continued running. | 529 | * continued running. |
530 | */ | 530 | */ |
531 | pmboxq->mbox_flag |= LPFC_MBX_WAKE; | ||
531 | pdone_q = (wait_queue_head_t *) pmboxq->context1; | 532 | pdone_q = (wait_queue_head_t *) pmboxq->context1; |
532 | if (pdone_q) | 533 | if (pdone_q) |
533 | wake_up_interruptible(pdone_q); | 534 | wake_up_interruptible(pdone_q); |
@@ -538,11 +539,32 @@ void | |||
538 | lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 539 | lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) |
539 | { | 540 | { |
540 | struct lpfc_dmabuf *mp; | 541 | struct lpfc_dmabuf *mp; |
542 | uint16_t rpi; | ||
543 | int rc; | ||
544 | |||
541 | mp = (struct lpfc_dmabuf *) (pmb->context1); | 545 | mp = (struct lpfc_dmabuf *) (pmb->context1); |
546 | |||
542 | if (mp) { | 547 | if (mp) { |
543 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 548 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
544 | kfree(mp); | 549 | kfree(mp); |
545 | } | 550 | } |
551 | |||
552 | /* | ||
553 | * If a REG_LOGIN succeeded after node is destroyed or node | ||
554 | * is in re-discovery driver need to cleanup the RPI. | ||
555 | */ | ||
556 | if (!(phba->fc_flag & FC_UNLOADING) && | ||
557 | (pmb->mb.mbxCommand == MBX_REG_LOGIN64) && | ||
558 | (!pmb->mb.mbxStatus)) { | ||
559 | |||
560 | rpi = pmb->mb.un.varWords[0]; | ||
561 | lpfc_unreg_login(phba, rpi, pmb); | ||
562 | pmb->mbox_cmpl=lpfc_sli_def_mbox_cmpl; | ||
563 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | ||
564 | if (rc != MBX_NOT_FINISHED) | ||
565 | return; | ||
566 | } | ||
567 | |||
546 | mempool_free( pmb, phba->mbox_mem_pool); | 568 | mempool_free( pmb, phba->mbox_mem_pool); |
547 | return; | 569 | return; |
548 | } | 570 | } |
@@ -693,25 +715,8 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) | |||
693 | } else { | 715 | } else { |
694 | spin_unlock_irq(phba->host->host_lock); | 716 | spin_unlock_irq(phba->host->host_lock); |
695 | /* Turn on IOCB processing */ | 717 | /* Turn on IOCB processing */ |
696 | for (i = 0; i < phba->sli.num_rings; i++) { | 718 | for (i = 0; i < phba->sli.num_rings; i++) |
697 | lpfc_sli_turn_on_ring(phba, i); | 719 | lpfc_sli_turn_on_ring(phba, i); |
698 | } | ||
699 | |||
700 | /* Free any lpfc_dmabuf's waiting for mbox cmd cmpls */ | ||
701 | while (!list_empty(&phba->freebufList)) { | ||
702 | struct lpfc_dmabuf *mp; | ||
703 | |||
704 | mp = NULL; | ||
705 | list_remove_head((&phba->freebufList), | ||
706 | mp, | ||
707 | struct lpfc_dmabuf, | ||
708 | list); | ||
709 | if (mp) { | ||
710 | lpfc_mbuf_free(phba, mp->virt, | ||
711 | mp->phys); | ||
712 | kfree(mp); | ||
713 | } | ||
714 | } | ||
715 | } | 720 | } |
716 | 721 | ||
717 | } while (process_next); | 722 | } while (process_next); |
@@ -833,6 +838,14 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, | |||
833 | * All other are passed to the completion callback. | 838 | * All other are passed to the completion callback. |
834 | */ | 839 | */ |
835 | if (pring->ringno == LPFC_ELS_RING) { | 840 | if (pring->ringno == LPFC_ELS_RING) { |
841 | if (cmdiocbp->iocb_flag & LPFC_DRIVER_ABORTED) { | ||
842 | cmdiocbp->iocb_flag &= | ||
843 | ~LPFC_DRIVER_ABORTED; | ||
844 | saveq->iocb.ulpStatus = | ||
845 | IOSTAT_LOCAL_REJECT; | ||
846 | saveq->iocb.un.ulpWord[4] = | ||
847 | IOERR_SLI_ABORTED; | ||
848 | } | ||
836 | spin_unlock_irqrestore(phba->host->host_lock, | 849 | spin_unlock_irqrestore(phba->host->host_lock, |
837 | iflag); | 850 | iflag); |
838 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | 851 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); |
@@ -1464,8 +1477,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | |||
1464 | int | 1477 | int |
1465 | lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | 1478 | lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) |
1466 | { | 1479 | { |
1480 | LIST_HEAD(completions); | ||
1467 | struct lpfc_iocbq *iocb, *next_iocb; | 1481 | struct lpfc_iocbq *iocb, *next_iocb; |
1468 | IOCB_t *icmd = NULL, *cmd = NULL; | 1482 | IOCB_t *cmd = NULL; |
1469 | int errcnt; | 1483 | int errcnt; |
1470 | 1484 | ||
1471 | errcnt = 0; | 1485 | errcnt = 0; |
@@ -1474,46 +1488,28 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
1474 | * First do the txq. | 1488 | * First do the txq. |
1475 | */ | 1489 | */ |
1476 | spin_lock_irq(phba->host->host_lock); | 1490 | spin_lock_irq(phba->host->host_lock); |
1477 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { | 1491 | list_splice_init(&pring->txq, &completions); |
1478 | list_del_init(&iocb->list); | ||
1479 | if (iocb->iocb_cmpl) { | ||
1480 | icmd = &iocb->iocb; | ||
1481 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
1482 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
1483 | spin_unlock_irq(phba->host->host_lock); | ||
1484 | (iocb->iocb_cmpl) (phba, iocb, iocb); | ||
1485 | spin_lock_irq(phba->host->host_lock); | ||
1486 | } else | ||
1487 | lpfc_sli_release_iocbq(phba, iocb); | ||
1488 | } | ||
1489 | pring->txq_cnt = 0; | 1492 | pring->txq_cnt = 0; |
1490 | INIT_LIST_HEAD(&(pring->txq)); | ||
1491 | 1493 | ||
1492 | /* Next issue ABTS for everything on the txcmplq */ | 1494 | /* Next issue ABTS for everything on the txcmplq */ |
1493 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { | 1495 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) |
1494 | cmd = &iocb->iocb; | 1496 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
1495 | 1497 | ||
1496 | /* | 1498 | spin_unlock_irq(phba->host->host_lock); |
1497 | * Imediate abort of IOCB, deque and call compl | ||
1498 | */ | ||
1499 | 1499 | ||
1500 | list_del_init(&iocb->list); | 1500 | while (!list_empty(&completions)) { |
1501 | pring->txcmplq_cnt--; | 1501 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); |
1502 | cmd = &iocb->iocb; | ||
1503 | list_del(&iocb->list); | ||
1502 | 1504 | ||
1503 | if (iocb->iocb_cmpl) { | 1505 | if (iocb->iocb_cmpl) { |
1504 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 1506 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
1505 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | 1507 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
1506 | spin_unlock_irq(phba->host->host_lock); | ||
1507 | (iocb->iocb_cmpl) (phba, iocb, iocb); | 1508 | (iocb->iocb_cmpl) (phba, iocb, iocb); |
1508 | spin_lock_irq(phba->host->host_lock); | ||
1509 | } else | 1509 | } else |
1510 | lpfc_sli_release_iocbq(phba, iocb); | 1510 | lpfc_sli_release_iocbq(phba, iocb); |
1511 | } | 1511 | } |
1512 | 1512 | ||
1513 | INIT_LIST_HEAD(&pring->txcmplq); | ||
1514 | pring->txcmplq_cnt = 0; | ||
1515 | spin_unlock_irq(phba->host->host_lock); | ||
1516 | |||
1517 | return errcnt; | 1513 | return errcnt; |
1518 | } | 1514 | } |
1519 | 1515 | ||
@@ -1588,6 +1584,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) | |||
1588 | hc_copy = readl(phba->HCregaddr); | 1584 | hc_copy = readl(phba->HCregaddr); |
1589 | writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr); | 1585 | writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr); |
1590 | readl(phba->HCregaddr); /* flush */ | 1586 | readl(phba->HCregaddr); /* flush */ |
1587 | phba->fc_flag |= FC_IGNORE_ERATT; | ||
1591 | 1588 | ||
1592 | if (readl(phba->HAregaddr) & HA_ERATT) { | 1589 | if (readl(phba->HAregaddr) & HA_ERATT) { |
1593 | /* Clear Chip error bit */ | 1590 | /* Clear Chip error bit */ |
@@ -1630,6 +1627,7 @@ clear_errat: | |||
1630 | } | 1627 | } |
1631 | 1628 | ||
1632 | restore_hc: | 1629 | restore_hc: |
1630 | phba->fc_flag &= ~FC_IGNORE_ERATT; | ||
1633 | writel(hc_copy, phba->HCregaddr); | 1631 | writel(hc_copy, phba->HCregaddr); |
1634 | readl(phba->HCregaddr); /* flush */ | 1632 | readl(phba->HCregaddr); /* flush */ |
1635 | } | 1633 | } |
@@ -1665,6 +1663,7 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) | |||
1665 | status &= ~HC_ERINT_ENA; | 1663 | status &= ~HC_ERINT_ENA; |
1666 | writel(status, phba->HCregaddr); | 1664 | writel(status, phba->HCregaddr); |
1667 | readl(phba->HCregaddr); /* flush */ | 1665 | readl(phba->HCregaddr); /* flush */ |
1666 | phba->fc_flag |= FC_IGNORE_ERATT; | ||
1668 | spin_unlock_irq(phba->host->host_lock); | 1667 | spin_unlock_irq(phba->host->host_lock); |
1669 | 1668 | ||
1670 | lpfc_kill_board(phba, pmb); | 1669 | lpfc_kill_board(phba, pmb); |
@@ -1674,6 +1673,9 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) | |||
1674 | if (retval != MBX_SUCCESS) { | 1673 | if (retval != MBX_SUCCESS) { |
1675 | if (retval != MBX_BUSY) | 1674 | if (retval != MBX_BUSY) |
1676 | mempool_free(pmb, phba->mbox_mem_pool); | 1675 | mempool_free(pmb, phba->mbox_mem_pool); |
1676 | spin_lock_irq(phba->host->host_lock); | ||
1677 | phba->fc_flag &= ~FC_IGNORE_ERATT; | ||
1678 | spin_unlock_irq(phba->host->host_lock); | ||
1677 | return 1; | 1679 | return 1; |
1678 | } | 1680 | } |
1679 | 1681 | ||
@@ -1700,6 +1702,7 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) | |||
1700 | } | 1702 | } |
1701 | spin_lock_irq(phba->host->host_lock); | 1703 | spin_lock_irq(phba->host->host_lock); |
1702 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 1704 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
1705 | phba->fc_flag &= ~FC_IGNORE_ERATT; | ||
1703 | spin_unlock_irq(phba->host->host_lock); | 1706 | spin_unlock_irq(phba->host->host_lock); |
1704 | 1707 | ||
1705 | psli->mbox_active = NULL; | 1708 | psli->mbox_active = NULL; |
@@ -1985,42 +1988,6 @@ lpfc_sli_hba_setup_exit: | |||
1985 | return rc; | 1988 | return rc; |
1986 | } | 1989 | } |
1987 | 1990 | ||
1988 | static void | ||
1989 | lpfc_mbox_abort(struct lpfc_hba * phba) | ||
1990 | { | ||
1991 | LPFC_MBOXQ_t *pmbox; | ||
1992 | MAILBOX_t *mb; | ||
1993 | |||
1994 | if (phba->sli.mbox_active) { | ||
1995 | del_timer_sync(&phba->sli.mbox_tmo); | ||
1996 | phba->work_hba_events &= ~WORKER_MBOX_TMO; | ||
1997 | pmbox = phba->sli.mbox_active; | ||
1998 | mb = &pmbox->mb; | ||
1999 | phba->sli.mbox_active = NULL; | ||
2000 | if (pmbox->mbox_cmpl) { | ||
2001 | mb->mbxStatus = MBX_NOT_FINISHED; | ||
2002 | (pmbox->mbox_cmpl) (phba, pmbox); | ||
2003 | } | ||
2004 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
2005 | } | ||
2006 | |||
2007 | /* Abort all the non active mailbox commands. */ | ||
2008 | spin_lock_irq(phba->host->host_lock); | ||
2009 | pmbox = lpfc_mbox_get(phba); | ||
2010 | while (pmbox) { | ||
2011 | mb = &pmbox->mb; | ||
2012 | if (pmbox->mbox_cmpl) { | ||
2013 | mb->mbxStatus = MBX_NOT_FINISHED; | ||
2014 | spin_unlock_irq(phba->host->host_lock); | ||
2015 | (pmbox->mbox_cmpl) (phba, pmbox); | ||
2016 | spin_lock_irq(phba->host->host_lock); | ||
2017 | } | ||
2018 | pmbox = lpfc_mbox_get(phba); | ||
2019 | } | ||
2020 | spin_unlock_irq(phba->host->host_lock); | ||
2021 | return; | ||
2022 | } | ||
2023 | |||
2024 | /*! lpfc_mbox_timeout | 1991 | /*! lpfc_mbox_timeout |
2025 | * | 1992 | * |
2026 | * \pre | 1993 | * \pre |
@@ -2055,6 +2022,8 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2055 | { | 2022 | { |
2056 | LPFC_MBOXQ_t *pmbox; | 2023 | LPFC_MBOXQ_t *pmbox; |
2057 | MAILBOX_t *mb; | 2024 | MAILBOX_t *mb; |
2025 | struct lpfc_sli *psli = &phba->sli; | ||
2026 | struct lpfc_sli_ring *pring; | ||
2058 | 2027 | ||
2059 | spin_lock_irq(phba->host->host_lock); | 2028 | spin_lock_irq(phba->host->host_lock); |
2060 | if (!(phba->work_hba_events & WORKER_MBOX_TMO)) { | 2029 | if (!(phba->work_hba_events & WORKER_MBOX_TMO)) { |
@@ -2062,8 +2031,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2062 | return; | 2031 | return; |
2063 | } | 2032 | } |
2064 | 2033 | ||
2065 | phba->work_hba_events &= ~WORKER_MBOX_TMO; | ||
2066 | |||
2067 | pmbox = phba->sli.mbox_active; | 2034 | pmbox = phba->sli.mbox_active; |
2068 | mb = &pmbox->mb; | 2035 | mb = &pmbox->mb; |
2069 | 2036 | ||
@@ -2078,17 +2045,32 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2078 | phba->sli.sli_flag, | 2045 | phba->sli.sli_flag, |
2079 | phba->sli.mbox_active); | 2046 | phba->sli.mbox_active); |
2080 | 2047 | ||
2081 | phba->sli.mbox_active = NULL; | 2048 | /* Setting state unknown so lpfc_sli_abort_iocb_ring |
2082 | if (pmbox->mbox_cmpl) { | 2049 | * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing |
2083 | mb->mbxStatus = MBX_NOT_FINISHED; | 2050 | * it to fail all oustanding SCSI IO. |
2084 | spin_unlock_irq(phba->host->host_lock); | 2051 | */ |
2085 | (pmbox->mbox_cmpl) (phba, pmbox); | 2052 | phba->hba_state = LPFC_STATE_UNKNOWN; |
2086 | spin_lock_irq(phba->host->host_lock); | 2053 | phba->work_hba_events &= ~WORKER_MBOX_TMO; |
2087 | } | 2054 | phba->fc_flag |= FC_ESTABLISH_LINK; |
2088 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2055 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
2089 | |||
2090 | spin_unlock_irq(phba->host->host_lock); | 2056 | spin_unlock_irq(phba->host->host_lock); |
2091 | lpfc_mbox_abort(phba); | 2057 | |
2058 | pring = &psli->ring[psli->fcp_ring]; | ||
2059 | lpfc_sli_abort_iocb_ring(phba, pring); | ||
2060 | |||
2061 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | ||
2062 | "%d:0316 Resetting board due to mailbox timeout\n", | ||
2063 | phba->brd_no); | ||
2064 | /* | ||
2065 | * lpfc_offline calls lpfc_sli_hba_down which will clean up | ||
2066 | * on oustanding mailbox commands. | ||
2067 | */ | ||
2068 | lpfc_offline_prep(phba); | ||
2069 | lpfc_offline(phba); | ||
2070 | lpfc_sli_brdrestart(phba); | ||
2071 | if (lpfc_online(phba) == 0) /* Initialize the HBA */ | ||
2072 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
2073 | lpfc_unblock_mgmt_io(phba); | ||
2092 | return; | 2074 | return; |
2093 | } | 2075 | } |
2094 | 2076 | ||
@@ -2320,9 +2302,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2320 | spin_unlock_irqrestore(phba->host->host_lock, | 2302 | spin_unlock_irqrestore(phba->host->host_lock, |
2321 | drvr_flag); | 2303 | drvr_flag); |
2322 | 2304 | ||
2323 | /* Can be in interrupt context, do not sleep */ | 2305 | msleep(1); |
2324 | /* (or might be called with interrupts disabled) */ | ||
2325 | mdelay(1); | ||
2326 | 2306 | ||
2327 | spin_lock_irqsave(phba->host->host_lock, drvr_flag); | 2307 | spin_lock_irqsave(phba->host->host_lock, drvr_flag); |
2328 | 2308 | ||
@@ -2430,7 +2410,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2430 | 2410 | ||
2431 | if (unlikely(phba->hba_state == LPFC_LINK_DOWN)) { | 2411 | if (unlikely(phba->hba_state == LPFC_LINK_DOWN)) { |
2432 | /* | 2412 | /* |
2433 | * Only CREATE_XRI, CLOSE_XRI, ABORT_XRI, and QUE_RING_BUF | 2413 | * Only CREATE_XRI, CLOSE_XRI, and QUE_RING_BUF |
2434 | * can be issued if the link is not up. | 2414 | * can be issued if the link is not up. |
2435 | */ | 2415 | */ |
2436 | switch (piocb->iocb.ulpCommand) { | 2416 | switch (piocb->iocb.ulpCommand) { |
@@ -2444,6 +2424,8 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2444 | piocb->iocb_cmpl = NULL; | 2424 | piocb->iocb_cmpl = NULL; |
2445 | /*FALLTHROUGH*/ | 2425 | /*FALLTHROUGH*/ |
2446 | case CMD_CREATE_XRI_CR: | 2426 | case CMD_CREATE_XRI_CR: |
2427 | case CMD_CLOSE_XRI_CN: | ||
2428 | case CMD_CLOSE_XRI_CX: | ||
2447 | break; | 2429 | break; |
2448 | default: | 2430 | default: |
2449 | goto iocb_busy; | 2431 | goto iocb_busy; |
@@ -2637,11 +2619,12 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba) | |||
2637 | int | 2619 | int |
2638 | lpfc_sli_hba_down(struct lpfc_hba * phba) | 2620 | lpfc_sli_hba_down(struct lpfc_hba * phba) |
2639 | { | 2621 | { |
2622 | LIST_HEAD(completions); | ||
2640 | struct lpfc_sli *psli; | 2623 | struct lpfc_sli *psli; |
2641 | struct lpfc_sli_ring *pring; | 2624 | struct lpfc_sli_ring *pring; |
2642 | LPFC_MBOXQ_t *pmb; | 2625 | LPFC_MBOXQ_t *pmb; |
2643 | struct lpfc_iocbq *iocb, *next_iocb; | 2626 | struct lpfc_iocbq *iocb; |
2644 | IOCB_t *icmd = NULL; | 2627 | IOCB_t *cmd = NULL; |
2645 | int i; | 2628 | int i; |
2646 | unsigned long flags = 0; | 2629 | unsigned long flags = 0; |
2647 | 2630 | ||
@@ -2649,7 +2632,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) | |||
2649 | lpfc_hba_down_prep(phba); | 2632 | lpfc_hba_down_prep(phba); |
2650 | 2633 | ||
2651 | spin_lock_irqsave(phba->host->host_lock, flags); | 2634 | spin_lock_irqsave(phba->host->host_lock, flags); |
2652 | |||
2653 | for (i = 0; i < psli->num_rings; i++) { | 2635 | for (i = 0; i < psli->num_rings; i++) { |
2654 | pring = &psli->ring[i]; | 2636 | pring = &psli->ring[i]; |
2655 | pring->flag |= LPFC_DEFERRED_RING_EVENT; | 2637 | pring->flag |= LPFC_DEFERRED_RING_EVENT; |
@@ -2658,28 +2640,25 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) | |||
2658 | * Error everything on the txq since these iocbs have not been | 2640 | * Error everything on the txq since these iocbs have not been |
2659 | * given to the FW yet. | 2641 | * given to the FW yet. |
2660 | */ | 2642 | */ |
2643 | list_splice_init(&pring->txq, &completions); | ||
2661 | pring->txq_cnt = 0; | 2644 | pring->txq_cnt = 0; |
2662 | 2645 | ||
2663 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { | 2646 | } |
2664 | list_del_init(&iocb->list); | 2647 | spin_unlock_irqrestore(phba->host->host_lock, flags); |
2665 | if (iocb->iocb_cmpl) { | ||
2666 | icmd = &iocb->iocb; | ||
2667 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
2668 | icmd->un.ulpWord[4] = IOERR_SLI_DOWN; | ||
2669 | spin_unlock_irqrestore(phba->host->host_lock, | ||
2670 | flags); | ||
2671 | (iocb->iocb_cmpl) (phba, iocb, iocb); | ||
2672 | spin_lock_irqsave(phba->host->host_lock, flags); | ||
2673 | } else | ||
2674 | lpfc_sli_release_iocbq(phba, iocb); | ||
2675 | } | ||
2676 | 2648 | ||
2677 | INIT_LIST_HEAD(&(pring->txq)); | 2649 | while (!list_empty(&completions)) { |
2650 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | ||
2651 | cmd = &iocb->iocb; | ||
2652 | list_del(&iocb->list); | ||
2678 | 2653 | ||
2654 | if (iocb->iocb_cmpl) { | ||
2655 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
2656 | cmd->un.ulpWord[4] = IOERR_SLI_DOWN; | ||
2657 | (iocb->iocb_cmpl) (phba, iocb, iocb); | ||
2658 | } else | ||
2659 | lpfc_sli_release_iocbq(phba, iocb); | ||
2679 | } | 2660 | } |
2680 | 2661 | ||
2681 | spin_unlock_irqrestore(phba->host->host_lock, flags); | ||
2682 | |||
2683 | /* Return any active mbox cmds */ | 2662 | /* Return any active mbox cmds */ |
2684 | del_timer_sync(&psli->mbox_tmo); | 2663 | del_timer_sync(&psli->mbox_tmo); |
2685 | spin_lock_irqsave(phba->host->host_lock, flags); | 2664 | spin_lock_irqsave(phba->host->host_lock, flags); |
@@ -2768,85 +2747,138 @@ lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2768 | } | 2747 | } |
2769 | 2748 | ||
2770 | static void | 2749 | static void |
2771 | lpfc_sli_abort_elsreq_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2750 | lpfc_sli_abort_els_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, |
2772 | struct lpfc_iocbq * rspiocb) | 2751 | struct lpfc_iocbq * rspiocb) |
2773 | { | 2752 | { |
2774 | struct lpfc_dmabuf *buf_ptr, *buf_ptr1; | 2753 | IOCB_t *irsp; |
2775 | /* Free the resources associated with the ELS_REQUEST64 IOCB the driver | 2754 | uint16_t abort_iotag, abort_context; |
2776 | * just aborted. | 2755 | struct lpfc_iocbq *abort_iocb, *rsp_ab_iocb; |
2777 | * In this case, context2 = cmd, context2->next = rsp, context3 = bpl | 2756 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; |
2778 | */ | 2757 | |
2779 | if (cmdiocb->context2) { | 2758 | abort_iocb = NULL; |
2780 | buf_ptr1 = (struct lpfc_dmabuf *) cmdiocb->context2; | 2759 | irsp = &rspiocb->iocb; |
2781 | 2760 | ||
2782 | /* Free the response IOCB before completing the abort | 2761 | spin_lock_irq(phba->host->host_lock); |
2783 | command. */ | ||
2784 | buf_ptr = NULL; | ||
2785 | list_remove_head((&buf_ptr1->list), buf_ptr, | ||
2786 | struct lpfc_dmabuf, list); | ||
2787 | if (buf_ptr) { | ||
2788 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | ||
2789 | kfree(buf_ptr); | ||
2790 | } | ||
2791 | lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys); | ||
2792 | kfree(buf_ptr1); | ||
2793 | } | ||
2794 | 2762 | ||
2795 | if (cmdiocb->context3) { | 2763 | if (irsp->ulpStatus) { |
2796 | buf_ptr = (struct lpfc_dmabuf *) cmdiocb->context3; | 2764 | abort_context = cmdiocb->iocb.un.acxri.abortContextTag; |
2797 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | 2765 | abort_iotag = cmdiocb->iocb.un.acxri.abortIoTag; |
2798 | kfree(buf_ptr); | 2766 | |
2767 | if (abort_iotag != 0 && abort_iotag <= phba->sli.last_iotag) | ||
2768 | abort_iocb = phba->sli.iocbq_lookup[abort_iotag]; | ||
2769 | |||
2770 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
2771 | "%d:0327 Cannot abort els iocb %p" | ||
2772 | " with tag %x context %x\n", | ||
2773 | phba->brd_no, abort_iocb, | ||
2774 | abort_iotag, abort_context); | ||
2775 | |||
2776 | /* | ||
2777 | * make sure we have the right iocbq before taking it | ||
2778 | * off the txcmplq and try to call completion routine. | ||
2779 | */ | ||
2780 | if (abort_iocb && | ||
2781 | abort_iocb->iocb.ulpContext == abort_context && | ||
2782 | abort_iocb->iocb_flag & LPFC_DRIVER_ABORTED) { | ||
2783 | list_del(&abort_iocb->list); | ||
2784 | pring->txcmplq_cnt--; | ||
2785 | |||
2786 | rsp_ab_iocb = lpfc_sli_get_iocbq(phba); | ||
2787 | if (rsp_ab_iocb == NULL) | ||
2788 | lpfc_sli_release_iocbq(phba, abort_iocb); | ||
2789 | else { | ||
2790 | abort_iocb->iocb_flag &= | ||
2791 | ~LPFC_DRIVER_ABORTED; | ||
2792 | rsp_ab_iocb->iocb.ulpStatus = | ||
2793 | IOSTAT_LOCAL_REJECT; | ||
2794 | rsp_ab_iocb->iocb.un.ulpWord[4] = | ||
2795 | IOERR_SLI_ABORTED; | ||
2796 | spin_unlock_irq(phba->host->host_lock); | ||
2797 | (abort_iocb->iocb_cmpl) | ||
2798 | (phba, abort_iocb, rsp_ab_iocb); | ||
2799 | spin_lock_irq(phba->host->host_lock); | ||
2800 | lpfc_sli_release_iocbq(phba, rsp_ab_iocb); | ||
2801 | } | ||
2802 | } | ||
2799 | } | 2803 | } |
2800 | 2804 | ||
2801 | lpfc_sli_release_iocbq(phba, cmdiocb); | 2805 | lpfc_sli_release_iocbq(phba, cmdiocb); |
2806 | spin_unlock_irq(phba->host->host_lock); | ||
2802 | return; | 2807 | return; |
2803 | } | 2808 | } |
2804 | 2809 | ||
2805 | int | 2810 | int |
2806 | lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba, | 2811 | lpfc_sli_issue_abort_iotag(struct lpfc_hba * phba, |
2807 | struct lpfc_sli_ring * pring, | 2812 | struct lpfc_sli_ring * pring, |
2808 | struct lpfc_iocbq * cmdiocb) | 2813 | struct lpfc_iocbq * cmdiocb) |
2809 | { | 2814 | { |
2810 | struct lpfc_iocbq *abtsiocbp; | 2815 | struct lpfc_iocbq *abtsiocbp; |
2811 | IOCB_t *icmd = NULL; | 2816 | IOCB_t *icmd = NULL; |
2812 | IOCB_t *iabt = NULL; | 2817 | IOCB_t *iabt = NULL; |
2818 | int retval = IOCB_ERROR; | ||
2819 | |||
2820 | /* There are certain command types we don't want | ||
2821 | * to abort. | ||
2822 | */ | ||
2823 | icmd = &cmdiocb->iocb; | ||
2824 | if ((icmd->ulpCommand == CMD_ABORT_XRI_CN) || | ||
2825 | (icmd->ulpCommand == CMD_CLOSE_XRI_CN)) | ||
2826 | return 0; | ||
2827 | |||
2828 | /* If we're unloading, interrupts are disabled so we | ||
2829 | * need to cleanup the iocb here. | ||
2830 | */ | ||
2831 | if (phba->fc_flag & FC_UNLOADING) | ||
2832 | goto abort_iotag_exit; | ||
2813 | 2833 | ||
2814 | /* issue ABTS for this IOCB based on iotag */ | 2834 | /* issue ABTS for this IOCB based on iotag */ |
2815 | abtsiocbp = lpfc_sli_get_iocbq(phba); | 2835 | abtsiocbp = lpfc_sli_get_iocbq(phba); |
2816 | if (abtsiocbp == NULL) | 2836 | if (abtsiocbp == NULL) |
2817 | return 0; | 2837 | return 0; |
2818 | 2838 | ||
2839 | /* This signals the response to set the correct status | ||
2840 | * before calling the completion handler. | ||
2841 | */ | ||
2842 | cmdiocb->iocb_flag |= LPFC_DRIVER_ABORTED; | ||
2843 | |||
2819 | iabt = &abtsiocbp->iocb; | 2844 | iabt = &abtsiocbp->iocb; |
2820 | icmd = &cmdiocb->iocb; | 2845 | iabt->un.acxri.abortType = ABORT_TYPE_ABTS; |
2821 | switch (icmd->ulpCommand) { | 2846 | iabt->un.acxri.abortContextTag = icmd->ulpContext; |
2822 | case CMD_ELS_REQUEST64_CR: | 2847 | iabt->un.acxri.abortIoTag = icmd->ulpIoTag; |
2823 | /* Even though we abort the ELS command, the firmware may access | 2848 | iabt->ulpLe = 1; |
2824 | * the BPL or other resources before it processes our | 2849 | iabt->ulpClass = icmd->ulpClass; |
2825 | * ABORT_MXRI64. Thus we must delay reusing the cmdiocb | ||
2826 | * resources till the actual abort request completes. | ||
2827 | */ | ||
2828 | abtsiocbp->context1 = (void *)((unsigned long)icmd->ulpCommand); | ||
2829 | abtsiocbp->context2 = cmdiocb->context2; | ||
2830 | abtsiocbp->context3 = cmdiocb->context3; | ||
2831 | cmdiocb->context2 = NULL; | ||
2832 | cmdiocb->context3 = NULL; | ||
2833 | abtsiocbp->iocb_cmpl = lpfc_sli_abort_elsreq_cmpl; | ||
2834 | break; | ||
2835 | default: | ||
2836 | lpfc_sli_release_iocbq(phba, abtsiocbp); | ||
2837 | return 0; | ||
2838 | } | ||
2839 | 2850 | ||
2840 | iabt->un.amxri.abortType = ABORT_TYPE_ABTS; | 2851 | if (phba->hba_state >= LPFC_LINK_UP) |
2841 | iabt->un.amxri.iotag32 = icmd->un.elsreq64.bdl.ulpIoTag32; | 2852 | iabt->ulpCommand = CMD_ABORT_XRI_CN; |
2853 | else | ||
2854 | iabt->ulpCommand = CMD_CLOSE_XRI_CN; | ||
2842 | 2855 | ||
2843 | iabt->ulpLe = 1; | 2856 | abtsiocbp->iocb_cmpl = lpfc_sli_abort_els_cmpl; |
2844 | iabt->ulpClass = CLASS3; | ||
2845 | iabt->ulpCommand = CMD_ABORT_MXRI64_CN; | ||
2846 | 2857 | ||
2847 | if (lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0) == IOCB_ERROR) { | 2858 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
2848 | lpfc_sli_release_iocbq(phba, abtsiocbp); | 2859 | "%d:0339 Abort xri x%x, original iotag x%x, abort " |
2849 | return 0; | 2860 | "cmd iotag x%x\n", |
2861 | phba->brd_no, iabt->un.acxri.abortContextTag, | ||
2862 | iabt->un.acxri.abortIoTag, abtsiocbp->iotag); | ||
2863 | retval = lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0); | ||
2864 | |||
2865 | abort_iotag_exit: | ||
2866 | |||
2867 | /* If we could not issue an abort dequeue the iocb and handle | ||
2868 | * the completion here. | ||
2869 | */ | ||
2870 | if (retval == IOCB_ERROR) { | ||
2871 | list_del(&cmdiocb->list); | ||
2872 | pring->txcmplq_cnt--; | ||
2873 | |||
2874 | if (cmdiocb->iocb_cmpl) { | ||
2875 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
2876 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
2877 | spin_unlock_irq(phba->host->host_lock); | ||
2878 | (cmdiocb->iocb_cmpl) (phba, cmdiocb, cmdiocb); | ||
2879 | spin_lock_irq(phba->host->host_lock); | ||
2880 | } else | ||
2881 | lpfc_sli_release_iocbq(phba, cmdiocb); | ||
2850 | } | 2882 | } |
2851 | 2883 | ||
2852 | return 1; | 2884 | return 1; |
@@ -2918,9 +2950,11 @@ void | |||
2918 | lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2950 | lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, |
2919 | struct lpfc_iocbq * rspiocb) | 2951 | struct lpfc_iocbq * rspiocb) |
2920 | { | 2952 | { |
2921 | spin_lock_irq(phba->host->host_lock); | 2953 | unsigned long iflags; |
2954 | |||
2955 | spin_lock_irqsave(phba->host->host_lock, iflags); | ||
2922 | lpfc_sli_release_iocbq(phba, cmdiocb); | 2956 | lpfc_sli_release_iocbq(phba, cmdiocb); |
2923 | spin_unlock_irq(phba->host->host_lock); | 2957 | spin_unlock_irqrestore(phba->host->host_lock, iflags); |
2924 | return; | 2958 | return; |
2925 | } | 2959 | } |
2926 | 2960 | ||
@@ -3043,22 +3077,22 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, | |||
3043 | timeout_req); | 3077 | timeout_req); |
3044 | spin_lock_irq(phba->host->host_lock); | 3078 | spin_lock_irq(phba->host->host_lock); |
3045 | 3079 | ||
3046 | if (timeleft == 0) { | 3080 | if (piocb->iocb_flag & LPFC_IO_WAKE) { |
3081 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
3082 | "%d:0331 IOCB wake signaled\n", | ||
3083 | phba->brd_no); | ||
3084 | } else if (timeleft == 0) { | ||
3047 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 3085 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
3048 | "%d:0338 IOCB wait timeout error - no " | 3086 | "%d:0338 IOCB wait timeout error - no " |
3049 | "wake response Data x%x\n", | 3087 | "wake response Data x%x\n", |
3050 | phba->brd_no, timeout); | 3088 | phba->brd_no, timeout); |
3051 | retval = IOCB_TIMEDOUT; | 3089 | retval = IOCB_TIMEDOUT; |
3052 | } else if (!(piocb->iocb_flag & LPFC_IO_WAKE)) { | 3090 | } else { |
3053 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 3091 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
3054 | "%d:0330 IOCB wake NOT set, " | 3092 | "%d:0330 IOCB wake NOT set, " |
3055 | "Data x%x x%lx\n", phba->brd_no, | 3093 | "Data x%x x%lx\n", phba->brd_no, |
3056 | timeout, (timeleft / jiffies)); | 3094 | timeout, (timeleft / jiffies)); |
3057 | retval = IOCB_TIMEDOUT; | 3095 | retval = IOCB_TIMEDOUT; |
3058 | } else { | ||
3059 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
3060 | "%d:0331 IOCB wake signaled\n", | ||
3061 | phba->brd_no); | ||
3062 | } | 3096 | } |
3063 | } else { | 3097 | } else { |
3064 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 3098 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
@@ -3087,8 +3121,6 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | |||
3087 | uint32_t timeout) | 3121 | uint32_t timeout) |
3088 | { | 3122 | { |
3089 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); | 3123 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); |
3090 | DECLARE_WAITQUEUE(wq_entry, current); | ||
3091 | uint32_t timeleft = 0; | ||
3092 | int retval; | 3124 | int retval; |
3093 | 3125 | ||
3094 | /* The caller must leave context1 empty. */ | 3126 | /* The caller must leave context1 empty. */ |
@@ -3101,27 +3133,25 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | |||
3101 | /* setup context field to pass wait_queue pointer to wake function */ | 3133 | /* setup context field to pass wait_queue pointer to wake function */ |
3102 | pmboxq->context1 = &done_q; | 3134 | pmboxq->context1 = &done_q; |
3103 | 3135 | ||
3104 | /* start to sleep before we wait, to avoid races */ | ||
3105 | set_current_state(TASK_INTERRUPTIBLE); | ||
3106 | add_wait_queue(&done_q, &wq_entry); | ||
3107 | |||
3108 | /* now issue the command */ | 3136 | /* now issue the command */ |
3109 | retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); | 3137 | retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); |
3110 | 3138 | ||
3111 | if (retval == MBX_BUSY || retval == MBX_SUCCESS) { | 3139 | if (retval == MBX_BUSY || retval == MBX_SUCCESS) { |
3112 | timeleft = schedule_timeout(timeout * HZ); | 3140 | wait_event_interruptible_timeout(done_q, |
3141 | pmboxq->mbox_flag & LPFC_MBX_WAKE, | ||
3142 | timeout * HZ); | ||
3143 | |||
3113 | pmboxq->context1 = NULL; | 3144 | pmboxq->context1 = NULL; |
3114 | /* if schedule_timeout returns 0, we timed out and were not | 3145 | /* |
3115 | woken up */ | 3146 | * if LPFC_MBX_WAKE flag is set the mailbox is completed |
3116 | if ((timeleft == 0) || signal_pending(current)) | 3147 | * else do not free the resources. |
3117 | retval = MBX_TIMEOUT; | 3148 | */ |
3118 | else | 3149 | if (pmboxq->mbox_flag & LPFC_MBX_WAKE) |
3119 | retval = MBX_SUCCESS; | 3150 | retval = MBX_SUCCESS; |
3151 | else | ||
3152 | retval = MBX_TIMEOUT; | ||
3120 | } | 3153 | } |
3121 | 3154 | ||
3122 | |||
3123 | set_current_state(TASK_RUNNING); | ||
3124 | remove_wait_queue(&done_q, &wq_entry); | ||
3125 | return retval; | 3155 | return retval; |
3126 | } | 3156 | } |
3127 | 3157 | ||
@@ -3184,6 +3214,11 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3184 | */ | 3214 | */ |
3185 | spin_lock(phba->host->host_lock); | 3215 | spin_lock(phba->host->host_lock); |
3186 | ha_copy = readl(phba->HAregaddr); | 3216 | ha_copy = readl(phba->HAregaddr); |
3217 | /* If somebody is waiting to handle an eratt don't process it | ||
3218 | * here. The brdkill function will do this. | ||
3219 | */ | ||
3220 | if (phba->fc_flag & FC_IGNORE_ERATT) | ||
3221 | ha_copy &= ~HA_ERATT; | ||
3187 | writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr); | 3222 | writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr); |
3188 | readl(phba->HAregaddr); /* flush */ | 3223 | readl(phba->HAregaddr); /* flush */ |
3189 | spin_unlock(phba->host->host_lock); | 3224 | spin_unlock(phba->host->host_lock); |