diff options
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 12 |
2 files changed, 13 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index ccc4ca194c60..913e08ee0b4a 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -250,6 +250,7 @@ struct lpfc_hba { | |||
250 | #define FC_LOOPBACK_MODE 0x40000 /* NPort is in Loopback mode */ | 250 | #define FC_LOOPBACK_MODE 0x40000 /* NPort is in Loopback mode */ |
251 | /* This flag is set while issuing */ | 251 | /* This flag is set while issuing */ |
252 | /* INIT_LINK mailbox command */ | 252 | /* INIT_LINK mailbox command */ |
253 | #define FC_IGNORE_ERATT 0x80000 /* intr handler should ignore ERATT */ | ||
253 | 254 | ||
254 | uint32_t fc_topology; /* link topology, from LINK INIT */ | 255 | uint32_t fc_topology; /* link topology, from LINK INIT */ |
255 | 256 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 645291efce08..1508b3f6639f 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -1584,6 +1584,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) | |||
1584 | hc_copy = readl(phba->HCregaddr); | 1584 | hc_copy = readl(phba->HCregaddr); |
1585 | writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr); | 1585 | writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr); |
1586 | readl(phba->HCregaddr); /* flush */ | 1586 | readl(phba->HCregaddr); /* flush */ |
1587 | phba->fc_flag |= FC_IGNORE_ERATT; | ||
1587 | 1588 | ||
1588 | if (readl(phba->HAregaddr) & HA_ERATT) { | 1589 | if (readl(phba->HAregaddr) & HA_ERATT) { |
1589 | /* Clear Chip error bit */ | 1590 | /* Clear Chip error bit */ |
@@ -1626,6 +1627,7 @@ clear_errat: | |||
1626 | } | 1627 | } |
1627 | 1628 | ||
1628 | restore_hc: | 1629 | restore_hc: |
1630 | phba->fc_flag &= ~FC_IGNORE_ERATT; | ||
1629 | writel(hc_copy, phba->HCregaddr); | 1631 | writel(hc_copy, phba->HCregaddr); |
1630 | readl(phba->HCregaddr); /* flush */ | 1632 | readl(phba->HCregaddr); /* flush */ |
1631 | } | 1633 | } |
@@ -1661,6 +1663,7 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) | |||
1661 | status &= ~HC_ERINT_ENA; | 1663 | status &= ~HC_ERINT_ENA; |
1662 | writel(status, phba->HCregaddr); | 1664 | writel(status, phba->HCregaddr); |
1663 | readl(phba->HCregaddr); /* flush */ | 1665 | readl(phba->HCregaddr); /* flush */ |
1666 | phba->fc_flag |= FC_IGNORE_ERATT; | ||
1664 | spin_unlock_irq(phba->host->host_lock); | 1667 | spin_unlock_irq(phba->host->host_lock); |
1665 | 1668 | ||
1666 | lpfc_kill_board(phba, pmb); | 1669 | lpfc_kill_board(phba, pmb); |
@@ -1670,6 +1673,9 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) | |||
1670 | if (retval != MBX_SUCCESS) { | 1673 | if (retval != MBX_SUCCESS) { |
1671 | if (retval != MBX_BUSY) | 1674 | if (retval != MBX_BUSY) |
1672 | 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); | ||
1673 | return 1; | 1679 | return 1; |
1674 | } | 1680 | } |
1675 | 1681 | ||
@@ -1696,6 +1702,7 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) | |||
1696 | } | 1702 | } |
1697 | spin_lock_irq(phba->host->host_lock); | 1703 | spin_lock_irq(phba->host->host_lock); |
1698 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 1704 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
1705 | phba->fc_flag &= ~FC_IGNORE_ERATT; | ||
1699 | spin_unlock_irq(phba->host->host_lock); | 1706 | spin_unlock_irq(phba->host->host_lock); |
1700 | 1707 | ||
1701 | psli->mbox_active = NULL; | 1708 | psli->mbox_active = NULL; |
@@ -3207,6 +3214,11 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3207 | */ | 3214 | */ |
3208 | spin_lock(phba->host->host_lock); | 3215 | spin_lock(phba->host->host_lock); |
3209 | 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; | ||
3210 | writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr); | 3222 | writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr); |
3211 | readl(phba->HAregaddr); /* flush */ | 3223 | readl(phba->HAregaddr); /* flush */ |
3212 | spin_unlock(phba->host->host_lock); | 3224 | spin_unlock(phba->host->host_lock); |