diff options
author | Jamie Wellnitz <Jamie.Wellnitz@emulex.com> | 2006-02-28 19:25:27 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-02-28 20:00:36 -0500 |
commit | 41415862a23f422b80eccc92cf885935139e2415 (patch) | |
tree | e3a9537653e472f15405778c4dcc678a56304848 /drivers/scsi/lpfc/lpfc_sli.c | |
parent | d9d959c41f013439508e0fa1d31f5644d8d626ef (diff) |
[SCSI] lpfc 8.1.2: Add ERROR and WARM_START modes for diagnostic purposes.
Add ERROR and WARM_START modes for diagnostic purposes.
Signed-off-by: Jamie Wellnitz <Jamie.Wellnitz@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 311 |
1 files changed, 204 insertions, 107 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 1f876328b44b..d6ffe26ae123 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-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 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 * |
@@ -513,7 +513,9 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
513 | case MBX_SET_MASK: | 513 | case MBX_SET_MASK: |
514 | case MBX_SET_SLIM: | 514 | case MBX_SET_SLIM: |
515 | case MBX_UNREG_D_ID: | 515 | case MBX_UNREG_D_ID: |
516 | case MBX_KILL_BOARD: | ||
516 | case MBX_CONFIG_FARP: | 517 | case MBX_CONFIG_FARP: |
518 | case MBX_BEACON: | ||
517 | case MBX_LOAD_AREA: | 519 | case MBX_LOAD_AREA: |
518 | case MBX_RUN_BIU_DIAG64: | 520 | case MBX_RUN_BIU_DIAG64: |
519 | case MBX_CONFIG_PORT: | 521 | case MBX_CONFIG_PORT: |
@@ -1512,98 +1514,162 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
1512 | return errcnt; | 1514 | return errcnt; |
1513 | } | 1515 | } |
1514 | 1516 | ||
1515 | /****************************************************************************** | 1517 | int |
1516 | * lpfc_sli_send_reset | 1518 | lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask) |
1517 | * | ||
1518 | * Note: After returning from this function, the HBA cannot be accessed for | ||
1519 | * 1 ms. Since we do not wish to delay in interrupt context, it is the | ||
1520 | * responsibility of the caller to perform the mdelay(1) and flush via readl(). | ||
1521 | ******************************************************************************/ | ||
1522 | static int | ||
1523 | lpfc_sli_send_reset(struct lpfc_hba * phba, uint16_t skip_post) | ||
1524 | { | 1519 | { |
1525 | MAILBOX_t *swpmb; | 1520 | uint32_t status; |
1526 | volatile uint32_t word0; | 1521 | int i = 0; |
1527 | void __iomem *to_slim; | 1522 | int retval = 0; |
1528 | unsigned long flags = 0; | ||
1529 | 1523 | ||
1530 | spin_lock_irqsave(phba->host->host_lock, flags); | 1524 | /* Read the HBA Host Status Register */ |
1525 | status = readl(phba->HSregaddr); | ||
1531 | 1526 | ||
1532 | /* A board reset must use REAL SLIM. */ | 1527 | /* |
1533 | phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE; | 1528 | * Check status register every 100ms for 5 retries, then every |
1529 | * 500ms for 5, then every 2.5 sec for 5, then reset board and | ||
1530 | * every 2.5 sec for 4. | ||
1531 | * Break our of the loop if errors occurred during init. | ||
1532 | */ | ||
1533 | while (((status & mask) != mask) && | ||
1534 | !(status & HS_FFERM) && | ||
1535 | i++ < 20) { | ||
1534 | 1536 | ||
1535 | word0 = 0; | 1537 | if (i <= 5) |
1536 | swpmb = (MAILBOX_t *) & word0; | 1538 | msleep(10); |
1537 | swpmb->mbxCommand = MBX_RESTART; | 1539 | else if (i <= 10) |
1538 | swpmb->mbxHc = 1; | 1540 | msleep(500); |
1541 | else | ||
1542 | msleep(2500); | ||
1539 | 1543 | ||
1540 | to_slim = phba->MBslimaddr; | 1544 | if (i == 15) { |
1541 | writel(*(uint32_t *) swpmb, to_slim); | 1545 | phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */ |
1542 | readl(to_slim); /* flush */ | 1546 | lpfc_sli_brdrestart(phba); |
1547 | } | ||
1548 | /* Read the HBA Host Status Register */ | ||
1549 | status = readl(phba->HSregaddr); | ||
1550 | } | ||
1543 | 1551 | ||
1544 | /* Only skip post after fc_ffinit is completed */ | 1552 | /* Check to see if any errors occurred during init */ |
1545 | if (skip_post) { | 1553 | if ((status & HS_FFERM) || (i >= 20)) { |
1546 | word0 = 1; /* This is really setting up word1 */ | 1554 | phba->hba_state = LPFC_HBA_ERROR; |
1547 | } else { | 1555 | retval = 1; |
1548 | word0 = 0; /* This is really setting up word1 */ | ||
1549 | } | 1556 | } |
1550 | to_slim = phba->MBslimaddr + sizeof (uint32_t); | ||
1551 | writel(*(uint32_t *) swpmb, to_slim); | ||
1552 | readl(to_slim); /* flush */ | ||
1553 | 1557 | ||
1554 | /* Turn off parity checking and serr during the physical reset */ | 1558 | return retval; |
1555 | pci_read_config_word(phba->pcidev, PCI_COMMAND, &phba->pci_cfg_value); | 1559 | } |
1556 | pci_write_config_word(phba->pcidev, PCI_COMMAND, | ||
1557 | (phba->pci_cfg_value & | ||
1558 | ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); | ||
1559 | 1560 | ||
1560 | writel(HC_INITFF, phba->HCregaddr); | 1561 | int |
1562 | lpfc_sli_brdkill(struct lpfc_hba * phba) | ||
1563 | { | ||
1564 | struct lpfc_sli *psli; | ||
1565 | LPFC_MBOXQ_t *pmb; | ||
1566 | uint32_t status; | ||
1567 | uint32_t ha_copy; | ||
1568 | int retval; | ||
1569 | int i = 0; | ||
1561 | 1570 | ||
1562 | phba->hba_state = LPFC_INIT_START; | 1571 | psli = &phba->sli; |
1563 | spin_unlock_irqrestore(phba->host->host_lock, flags); | ||
1564 | 1572 | ||
1565 | return 0; | 1573 | /* Kill HBA */ |
1574 | lpfc_printf_log(phba, | ||
1575 | KERN_INFO, | ||
1576 | LOG_SLI, | ||
1577 | "%d:0329 Kill HBA Data: x%x x%x\n", | ||
1578 | phba->brd_no, | ||
1579 | phba->hba_state, | ||
1580 | psli->sli_flag); | ||
1581 | |||
1582 | if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, | ||
1583 | GFP_ATOMIC)) == 0) { | ||
1584 | return 1; | ||
1585 | } | ||
1586 | |||
1587 | /* Disable the error attention */ | ||
1588 | spin_lock_irq(phba->host->host_lock); | ||
1589 | status = readl(phba->HCregaddr); | ||
1590 | status &= ~HC_ERINT_ENA; | ||
1591 | writel(status, phba->HCregaddr); | ||
1592 | readl(phba->HCregaddr); /* flush */ | ||
1593 | spin_unlock_irq(phba->host->host_lock); | ||
1594 | |||
1595 | lpfc_kill_board(phba, pmb); | ||
1596 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | ||
1597 | retval = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | ||
1598 | |||
1599 | if (retval != MBX_SUCCESS) { | ||
1600 | if (retval != MBX_BUSY) | ||
1601 | mempool_free(pmb, phba->mbox_mem_pool); | ||
1602 | return 1; | ||
1603 | } | ||
1604 | |||
1605 | mempool_free(pmb, phba->mbox_mem_pool); | ||
1606 | |||
1607 | /* There is no completion for a KILL_BOARD mbox cmd. Check for an error | ||
1608 | * attention every 100ms for 3 seconds. If we don't get ERATT after | ||
1609 | * 3 seconds we still set HBA_ERROR state because the status of the | ||
1610 | * board is now undefined. | ||
1611 | */ | ||
1612 | ha_copy = readl(phba->HAregaddr); | ||
1613 | |||
1614 | while ((i++ < 30) && !(ha_copy & HA_ERATT)) { | ||
1615 | mdelay(100); | ||
1616 | ha_copy = readl(phba->HAregaddr); | ||
1617 | } | ||
1618 | |||
1619 | del_timer_sync(&psli->mbox_tmo); | ||
1620 | |||
1621 | spin_lock_irq(phba->host->host_lock); | ||
1622 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
1623 | spin_unlock_irq(phba->host->host_lock); | ||
1624 | |||
1625 | psli->mbox_active = NULL; | ||
1626 | lpfc_hba_down_post(phba); | ||
1627 | phba->hba_state = LPFC_HBA_ERROR; | ||
1628 | |||
1629 | return (ha_copy & HA_ERATT ? 0 : 1); | ||
1566 | } | 1630 | } |
1567 | 1631 | ||
1568 | static int | 1632 | int |
1569 | lpfc_sli_brdreset(struct lpfc_hba * phba, uint16_t skip_post) | 1633 | lpfc_sli_brdreset(struct lpfc_hba * phba) |
1570 | { | 1634 | { |
1635 | struct lpfc_sli *psli; | ||
1571 | struct lpfc_sli_ring *pring; | 1636 | struct lpfc_sli_ring *pring; |
1637 | uint16_t cfg_value; | ||
1572 | int i; | 1638 | int i; |
1573 | struct lpfc_dmabuf *mp, *next_mp; | ||
1574 | unsigned long flags = 0; | ||
1575 | |||
1576 | lpfc_sli_send_reset(phba, skip_post); | ||
1577 | mdelay(1); | ||
1578 | 1639 | ||
1579 | spin_lock_irqsave(phba->host->host_lock, flags); | 1640 | psli = &phba->sli; |
1580 | /* Risk the write on flush case ie no delay after the readl */ | ||
1581 | readl(phba->HCregaddr); /* flush */ | ||
1582 | /* Now toggle INITFF bit set by lpfc_sli_send_reset */ | ||
1583 | writel(0, phba->HCregaddr); | ||
1584 | readl(phba->HCregaddr); /* flush */ | ||
1585 | 1641 | ||
1586 | /* Restore PCI cmd register */ | 1642 | /* Reset HBA */ |
1587 | pci_write_config_word(phba->pcidev, PCI_COMMAND, phba->pci_cfg_value); | 1643 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
1644 | "%d:0325 Reset HBA Data: x%x x%x\n", phba->brd_no, | ||
1645 | phba->hba_state, psli->sli_flag); | ||
1588 | 1646 | ||
1589 | /* perform board reset */ | 1647 | /* perform board reset */ |
1590 | phba->fc_eventTag = 0; | 1648 | phba->fc_eventTag = 0; |
1591 | phba->fc_myDID = 0; | 1649 | phba->fc_myDID = 0; |
1592 | phba->fc_prevDID = Mask_DID; | 1650 | phba->fc_prevDID = 0; |
1593 | 1651 | ||
1594 | /* Reset HBA */ | 1652 | psli->sli_flag = 0; |
1595 | lpfc_printf_log(phba, | 1653 | |
1596 | KERN_INFO, | 1654 | /* Turn off parity checking and serr during the physical reset */ |
1597 | LOG_SLI, | 1655 | pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value); |
1598 | "%d:0325 Reset HBA Data: x%x x%x x%x\n", | 1656 | pci_write_config_word(phba->pcidev, PCI_COMMAND, |
1599 | phba->brd_no, | 1657 | (cfg_value & |
1600 | phba->hba_state, | 1658 | ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); |
1601 | phba->sli.sli_flag, | 1659 | |
1602 | skip_post); | 1660 | /* Now toggle INITFF bit in the Host Control Register */ |
1661 | writel(HC_INITFF, phba->HCregaddr); | ||
1662 | mdelay(1); | ||
1663 | readl(phba->HCregaddr); /* flush */ | ||
1664 | writel(0, phba->HCregaddr); | ||
1665 | readl(phba->HCregaddr); /* flush */ | ||
1666 | |||
1667 | /* Restore PCI cmd register */ | ||
1668 | pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value); | ||
1603 | 1669 | ||
1604 | /* Initialize relevant SLI info */ | 1670 | /* Initialize relevant SLI info */ |
1605 | for (i = 0; i < phba->sli.num_rings; i++) { | 1671 | for (i = 0; i < psli->num_rings; i++) { |
1606 | pring = &phba->sli.ring[i]; | 1672 | pring = &psli->ring[i]; |
1607 | pring->flag = 0; | 1673 | pring->flag = 0; |
1608 | pring->rspidx = 0; | 1674 | pring->rspidx = 0; |
1609 | pring->next_cmdidx = 0; | 1675 | pring->next_cmdidx = 0; |
@@ -1611,27 +1677,62 @@ lpfc_sli_brdreset(struct lpfc_hba * phba, uint16_t skip_post) | |||
1611 | pring->cmdidx = 0; | 1677 | pring->cmdidx = 0; |
1612 | pring->missbufcnt = 0; | 1678 | pring->missbufcnt = 0; |
1613 | } | 1679 | } |
1614 | spin_unlock_irqrestore(phba->host->host_lock, flags); | ||
1615 | 1680 | ||
1616 | if (skip_post) { | 1681 | phba->hba_state = LPFC_WARM_START; |
1617 | mdelay(100); | 1682 | return 0; |
1683 | } | ||
1684 | |||
1685 | int | ||
1686 | lpfc_sli_brdrestart(struct lpfc_hba * phba) | ||
1687 | { | ||
1688 | MAILBOX_t *mb; | ||
1689 | struct lpfc_sli *psli; | ||
1690 | uint16_t skip_post; | ||
1691 | volatile uint32_t word0; | ||
1692 | void __iomem *to_slim; | ||
1693 | |||
1694 | spin_lock_irq(phba->host->host_lock); | ||
1695 | |||
1696 | psli = &phba->sli; | ||
1697 | |||
1698 | /* Restart HBA */ | ||
1699 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
1700 | "%d:0328 Restart HBA Data: x%x x%x\n", phba->brd_no, | ||
1701 | phba->hba_state, psli->sli_flag); | ||
1702 | |||
1703 | word0 = 0; | ||
1704 | mb = (MAILBOX_t *) &word0; | ||
1705 | mb->mbxCommand = MBX_RESTART; | ||
1706 | mb->mbxHc = 1; | ||
1707 | |||
1708 | to_slim = phba->MBslimaddr; | ||
1709 | writel(*(uint32_t *) mb, to_slim); | ||
1710 | readl(to_slim); /* flush */ | ||
1711 | |||
1712 | /* Only skip post after fc_ffinit is completed */ | ||
1713 | if (phba->hba_state) { | ||
1714 | skip_post = 1; | ||
1715 | word0 = 1; /* This is really setting up word1 */ | ||
1618 | } else { | 1716 | } else { |
1619 | mdelay(2000); | 1717 | skip_post = 0; |
1718 | word0 = 0; /* This is really setting up word1 */ | ||
1620 | } | 1719 | } |
1720 | to_slim = (uint8_t *) phba->MBslimaddr + sizeof (uint32_t); | ||
1721 | writel(*(uint32_t *) mb, to_slim); | ||
1722 | readl(to_slim); /* flush */ | ||
1621 | 1723 | ||
1622 | spin_lock_irqsave(phba->host->host_lock, flags); | 1724 | lpfc_sli_brdreset(phba); |
1623 | /* Cleanup preposted buffers on the ELS ring */ | ||
1624 | pring = &phba->sli.ring[LPFC_ELS_RING]; | ||
1625 | list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { | ||
1626 | list_del(&mp->list); | ||
1627 | pring->postbufq_cnt--; | ||
1628 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
1629 | kfree(mp); | ||
1630 | } | ||
1631 | spin_unlock_irqrestore(phba->host->host_lock, flags); | ||
1632 | 1725 | ||
1633 | for (i = 0; i < phba->sli.num_rings; i++) | 1726 | phba->hba_state = LPFC_INIT_START; |
1634 | lpfc_sli_abort_iocb_ring(phba, &phba->sli.ring[i]); | 1727 | |
1728 | spin_unlock_irq(phba->host->host_lock); | ||
1729 | |||
1730 | if (skip_post) | ||
1731 | mdelay(100); | ||
1732 | else | ||
1733 | mdelay(2000); | ||
1734 | |||
1735 | lpfc_hba_down_post(phba); | ||
1635 | 1736 | ||
1636 | return 0; | 1737 | return 0; |
1637 | } | 1738 | } |
@@ -1691,7 +1792,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
1691 | } | 1792 | } |
1692 | 1793 | ||
1693 | if (i == 15) { | 1794 | if (i == 15) { |
1694 | lpfc_sli_brdreset(phba, 0); | 1795 | phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */ |
1796 | lpfc_sli_brdrestart(phba); | ||
1695 | } | 1797 | } |
1696 | /* Read the HBA Host Status Register */ | 1798 | /* Read the HBA Host Status Register */ |
1697 | status = readl(phba->HSregaddr); | 1799 | status = readl(phba->HSregaddr); |
@@ -1735,8 +1837,8 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba) | |||
1735 | } | 1837 | } |
1736 | 1838 | ||
1737 | while (resetcount < 2 && !done) { | 1839 | while (resetcount < 2 && !done) { |
1738 | phba->hba_state = 0; | 1840 | phba->hba_state = LPFC_STATE_UNKNOWN; |
1739 | lpfc_sli_brdreset(phba, 0); | 1841 | lpfc_sli_brdrestart(phba); |
1740 | msleep(2500); | 1842 | msleep(2500); |
1741 | rc = lpfc_sli_chipset_init(phba); | 1843 | rc = lpfc_sli_chipset_init(phba); |
1742 | if (rc) | 1844 | if (rc) |
@@ -1920,6 +2022,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
1920 | mb = &pmbox->mb; | 2022 | mb = &pmbox->mb; |
1921 | status = MBX_SUCCESS; | 2023 | status = MBX_SUCCESS; |
1922 | 2024 | ||
2025 | if (phba->hba_state == LPFC_HBA_ERROR) { | ||
2026 | spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); | ||
2027 | |||
2028 | /* Mbox command <mbxCommand> cannot issue */ | ||
2029 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) | ||
2030 | return (MBX_NOT_FINISHED); | ||
2031 | } | ||
2032 | |||
1923 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { | 2033 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { |
1924 | /* Polling for a mbox command when another one is already active | 2034 | /* Polling for a mbox command when another one is already active |
1925 | * is not allowed in SLI. Also, the driver must have established | 2035 | * is not allowed in SLI. Also, the driver must have established |
@@ -2002,7 +2112,8 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2002 | 2112 | ||
2003 | /* If we are not polling, we MUST be in SLI2 mode */ | 2113 | /* If we are not polling, we MUST be in SLI2 mode */ |
2004 | if (flag != MBX_POLL) { | 2114 | if (flag != MBX_POLL) { |
2005 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { | 2115 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE) && |
2116 | (mb->mbxCommand != MBX_KILL_BOARD)) { | ||
2006 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2117 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2007 | spin_unlock_irqrestore(phba->host->host_lock, | 2118 | spin_unlock_irqrestore(phba->host->host_lock, |
2008 | drvr_flag); | 2119 | drvr_flag); |
@@ -2035,7 +2146,8 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2035 | /* First copy command data to host SLIM area */ | 2146 | /* First copy command data to host SLIM area */ |
2036 | lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, MAILBOX_CMD_SIZE); | 2147 | lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, MAILBOX_CMD_SIZE); |
2037 | } else { | 2148 | } else { |
2038 | if (mb->mbxCommand == MBX_CONFIG_PORT) { | 2149 | if (mb->mbxCommand == MBX_CONFIG_PORT || |
2150 | mb->mbxCommand == MBX_KILL_BOARD) { | ||
2039 | /* copy command data into host mbox for cmpl */ | 2151 | /* copy command data into host mbox for cmpl */ |
2040 | lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, | 2152 | lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, |
2041 | MAILBOX_CMD_SIZE); | 2153 | MAILBOX_CMD_SIZE); |
@@ -2086,8 +2198,9 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2086 | ha_copy = readl(phba->HAregaddr); | 2198 | ha_copy = readl(phba->HAregaddr); |
2087 | 2199 | ||
2088 | /* Wait for command to complete */ | 2200 | /* Wait for command to complete */ |
2089 | while (((word0 & OWN_CHIP) == OWN_CHIP) | 2201 | while (((word0 & OWN_CHIP) == OWN_CHIP) || |
2090 | || !(ha_copy & HA_MBATT)) { | 2202 | (!(ha_copy & HA_MBATT) && |
2203 | (phba->hba_state > LPFC_WARM_START))) { | ||
2091 | if (i++ >= 100) { | 2204 | if (i++ >= 100) { |
2092 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2205 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2093 | spin_unlock_irqrestore(phba->host->host_lock, | 2206 | spin_unlock_irqrestore(phba->host->host_lock, |
@@ -2455,15 +2568,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) | |||
2455 | 2568 | ||
2456 | spin_unlock_irqrestore(phba->host->host_lock, flags); | 2569 | spin_unlock_irqrestore(phba->host->host_lock, flags); |
2457 | 2570 | ||
2458 | /* | ||
2459 | * Provided the hba is not in an error state, reset it. It is not | ||
2460 | * capable of IO anymore. | ||
2461 | */ | ||
2462 | if (phba->hba_state != LPFC_HBA_ERROR) { | ||
2463 | phba->hba_state = LPFC_INIT_START; | ||
2464 | lpfc_sli_brdreset(phba, 1); | ||
2465 | } | ||
2466 | |||
2467 | return 1; | 2571 | return 1; |
2468 | } | 2572 | } |
2469 | 2573 | ||
@@ -2976,13 +3080,6 @@ lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs) | |||
2976 | /* Clear Chip error bit */ | 3080 | /* Clear Chip error bit */ |
2977 | writel(HA_ERATT, phba->HAregaddr); | 3081 | writel(HA_ERATT, phba->HAregaddr); |
2978 | readl(phba->HAregaddr); /* flush */ | 3082 | readl(phba->HAregaddr); /* flush */ |
2979 | |||
2980 | /* | ||
2981 | * Reseting the HBA is the only reliable way | ||
2982 | * to shutdown interrupt when there is a | ||
2983 | * ERROR. | ||
2984 | */ | ||
2985 | lpfc_sli_send_reset(phba, 1); | ||
2986 | } | 3083 | } |
2987 | 3084 | ||
2988 | spin_lock(phba->host->host_lock); | 3085 | spin_lock(phba->host->host_lock); |