aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c99
5 files changed, 100 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 2f67a8a92599..087c44539a16 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -197,6 +197,7 @@ struct lpfc_hba {
197#define LPFC_HBA_READY 32 197#define LPFC_HBA_READY 32
198#define LPFC_HBA_ERROR -1 198#define LPFC_HBA_ERROR -1
199 199
200 int32_t stopped; /* HBA has not been restarted since last ERATT */
200 uint8_t fc_linkspeed; /* Link speed after last READ_LA */ 201 uint8_t fc_linkspeed; /* Link speed after last READ_LA */
201 202
202 uint32_t fc_eventTag; /* event tag for link attention */ 203 uint32_t fc_eventTag; /* event tag for link attention */
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index f716c1d85f41..fad607b2e6f4 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -139,6 +139,7 @@ struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
139void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); 139void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
140uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); 140uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
141 141
142void lpfc_reset_barrier(struct lpfc_hba * phba);
142int lpfc_sli_brdready(struct lpfc_hba *, uint32_t); 143int lpfc_sli_brdready(struct lpfc_hba *, uint32_t);
143int lpfc_sli_brdkill(struct lpfc_hba *); 144int lpfc_sli_brdkill(struct lpfc_hba *);
144int lpfc_sli_brdreset(struct lpfc_hba *); 145int lpfc_sli_brdreset(struct lpfc_hba *);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 82704148d5d4..f54089fe4732 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -155,6 +155,7 @@ lpfc_work_list_done(struct lpfc_hba * phba)
155 case LPFC_EVT_WARM_START: 155 case LPFC_EVT_WARM_START:
156 if (phba->hba_state >= LPFC_LINK_DOWN) 156 if (phba->hba_state >= LPFC_LINK_DOWN)
157 lpfc_offline(phba); 157 lpfc_offline(phba);
158 lpfc_reset_barrier(phba);
158 lpfc_sli_brdreset(phba); 159 lpfc_sli_brdreset(phba);
159 lpfc_hba_down_post(phba); 160 lpfc_hba_down_post(phba);
160 *(int *)(evtp->evt_arg1) = 161 *(int *)(evtp->evt_arg1) =
@@ -164,7 +165,8 @@ lpfc_work_list_done(struct lpfc_hba * phba)
164 case LPFC_EVT_KILL: 165 case LPFC_EVT_KILL:
165 if (phba->hba_state >= LPFC_LINK_DOWN) 166 if (phba->hba_state >= LPFC_LINK_DOWN)
166 lpfc_offline(phba); 167 lpfc_offline(phba);
167 *(int *)(evtp->evt_arg1) = lpfc_sli_brdkill(phba); 168 *(int *)(evtp->evt_arg1)
169 = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba);
168 complete((struct completion *)(evtp->evt_arg2)); 170 complete((struct completion *)(evtp->evt_arg2));
169 break; 171 break;
170 } 172 }
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index a2e15436730e..66d5d003555d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -464,8 +464,6 @@ lpfc_hba_down_prep(struct lpfc_hba * phba)
464 lpfc_els_flush_cmd(phba); 464 lpfc_els_flush_cmd(phba);
465 lpfc_disc_flush_list(phba); 465 lpfc_disc_flush_list(phba);
466 466
467 /* Disable SLI2 since we disabled interrupts */
468 phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE;
469 return (0); 467 return (0);
470} 468}
471 469
@@ -526,6 +524,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
526 phba->work_status[0], phba->work_status[1]); 524 phba->work_status[0], phba->work_status[1]);
527 spin_lock_irq(phba->host->host_lock); 525 spin_lock_irq(phba->host->host_lock);
528 phba->fc_flag |= FC_ESTABLISH_LINK; 526 phba->fc_flag |= FC_ESTABLISH_LINK;
527 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
529 spin_unlock_irq(phba->host->host_lock); 528 spin_unlock_irq(phba->host->host_lock);
530 529
531 /* 530 /*
@@ -559,6 +558,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
559 phba->brd_no, phba->work_hs, 558 phba->brd_no, phba->work_hs,
560 phba->work_status[0], phba->work_status[1]); 559 phba->work_status[0], phba->work_status[1]);
561 560
561 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
562 lpfc_offline(phba); 562 lpfc_offline(phba);
563 phba->hba_state = LPFC_HBA_ERROR; 563 phba->hba_state = LPFC_HBA_ERROR;
564 lpfc_hba_down_post(phba); 564 lpfc_hba_down_post(phba);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 764aadbec71b..bb69a7a1ec59 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1566,6 +1566,79 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask)
1566 return retval; 1566 return retval;
1567} 1567}
1568 1568
1569#define BARRIER_TEST_PATTERN (0xdeadbeef)
1570
1571void lpfc_reset_barrier(struct lpfc_hba * phba)
1572{
1573 uint32_t * resp_buf;
1574 uint32_t * mbox_buf;
1575 volatile uint32_t mbox;
1576 uint32_t hc_copy;
1577 int i;
1578 uint8_t hdrtype;
1579
1580 pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
1581 if (hdrtype != 0x80 ||
1582 (FC_JEDEC_ID(phba->vpd.rev.biuRev) != HELIOS_JEDEC_ID &&
1583 FC_JEDEC_ID(phba->vpd.rev.biuRev) != THOR_JEDEC_ID))
1584 return;
1585
1586 /*
1587 * Tell the other part of the chip to suspend temporarily all
1588 * its DMA activity.
1589 */
1590 resp_buf = (uint32_t *)phba->MBslimaddr;
1591
1592 /* Disable the error attention */
1593 hc_copy = readl(phba->HCregaddr);
1594 writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr);
1595 readl(phba->HCregaddr); /* flush */
1596
1597 if (readl(phba->HAregaddr) & HA_ERATT) {
1598 /* Clear Chip error bit */
1599 writel(HA_ERATT, phba->HAregaddr);
1600 phba->stopped = 1;
1601 }
1602
1603 mbox = 0;
1604 ((MAILBOX_t *)&mbox)->mbxCommand = MBX_KILL_BOARD;
1605 ((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP;
1606
1607 writel(BARRIER_TEST_PATTERN, (resp_buf + 1));
1608 mbox_buf = (uint32_t *)phba->MBslimaddr;
1609 writel(mbox, mbox_buf);
1610
1611 for (i = 0;
1612 readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN) && i < 50; i++)
1613 mdelay(1);
1614
1615 if (readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN)) {
1616 if (phba->sli.sli_flag & LPFC_SLI2_ACTIVE ||
1617 phba->stopped)
1618 goto restore_hc;
1619 else
1620 goto clear_errat;
1621 }
1622
1623 ((MAILBOX_t *)&mbox)->mbxOwner = OWN_HOST;
1624 for (i = 0; readl(resp_buf) != mbox && i < 500; i++)
1625 mdelay(1);
1626
1627clear_errat:
1628
1629 while (!(readl(phba->HAregaddr) & HA_ERATT) && ++i < 500)
1630 mdelay(1);
1631
1632 if (readl(phba->HAregaddr) & HA_ERATT) {
1633 writel(HA_ERATT, phba->HAregaddr);
1634 phba->stopped = 1;
1635 }
1636
1637restore_hc:
1638 writel(hc_copy, phba->HCregaddr);
1639 readl(phba->HCregaddr); /* flush */
1640}
1641
1569int 1642int
1570lpfc_sli_brdkill(struct lpfc_hba * phba) 1643lpfc_sli_brdkill(struct lpfc_hba * phba)
1571{ 1644{
@@ -1588,9 +1661,8 @@ lpfc_sli_brdkill(struct lpfc_hba * phba)
1588 psli->sli_flag); 1661 psli->sli_flag);
1589 1662
1590 if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, 1663 if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
1591 GFP_ATOMIC)) == 0) { 1664 GFP_KERNEL)) == 0)
1592 return 1; 1665 return 1;
1593 }
1594 1666
1595 /* Disable the error attention */ 1667 /* Disable the error attention */
1596 spin_lock_irq(phba->host->host_lock); 1668 spin_lock_irq(phba->host->host_lock);
@@ -1610,6 +1682,8 @@ lpfc_sli_brdkill(struct lpfc_hba * phba)
1610 return 1; 1682 return 1;
1611 } 1683 }
1612 1684
1685 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
1686
1613 mempool_free(pmb, phba->mbox_mem_pool); 1687 mempool_free(pmb, phba->mbox_mem_pool);
1614 1688
1615 /* There is no completion for a KILL_BOARD mbox cmd. Check for an error 1689 /* There is no completion for a KILL_BOARD mbox cmd. Check for an error
@@ -1625,7 +1699,10 @@ lpfc_sli_brdkill(struct lpfc_hba * phba)
1625 } 1699 }
1626 1700
1627 del_timer_sync(&psli->mbox_tmo); 1701 del_timer_sync(&psli->mbox_tmo);
1628 1702 if (ha_copy & HA_ERATT) {
1703 writel(HA_ERATT, phba->HAregaddr);
1704 phba->stopped = 1;
1705 }
1629 spin_lock_irq(phba->host->host_lock); 1706 spin_lock_irq(phba->host->host_lock);
1630 psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; 1707 psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
1631 spin_unlock_irq(phba->host->host_lock); 1708 spin_unlock_irq(phba->host->host_lock);
@@ -1665,6 +1742,7 @@ lpfc_sli_brdreset(struct lpfc_hba * phba)
1665 (cfg_value & 1742 (cfg_value &
1666 ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); 1743 ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
1667 1744
1745 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
1668 /* Now toggle INITFF bit in the Host Control Register */ 1746 /* Now toggle INITFF bit in the Host Control Register */
1669 writel(HC_INITFF, phba->HCregaddr); 1747 writel(HC_INITFF, phba->HCregaddr);
1670 mdelay(1); 1748 mdelay(1);
@@ -1713,6 +1791,8 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba)
1713 mb->mbxCommand = MBX_RESTART; 1791 mb->mbxCommand = MBX_RESTART;
1714 mb->mbxHc = 1; 1792 mb->mbxHc = 1;
1715 1793
1794 lpfc_reset_barrier(phba);
1795
1716 to_slim = phba->MBslimaddr; 1796 to_slim = phba->MBslimaddr;
1717 writel(*(uint32_t *) mb, to_slim); 1797 writel(*(uint32_t *) mb, to_slim);
1718 readl(to_slim); /* flush */ 1798 readl(to_slim); /* flush */
@@ -1730,7 +1810,7 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba)
1730 readl(to_slim); /* flush */ 1810 readl(to_slim); /* flush */
1731 1811
1732 lpfc_sli_brdreset(phba); 1812 lpfc_sli_brdreset(phba);
1733 1813 phba->stopped = 0;
1734 phba->hba_state = LPFC_INIT_START; 1814 phba->hba_state = LPFC_INIT_START;
1735 1815
1736 spin_unlock_irq(phba->host->host_lock); 1816 spin_unlock_irq(phba->host->host_lock);
@@ -2038,6 +2118,13 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
2038 return (MBX_NOT_FINISHED); 2118 return (MBX_NOT_FINISHED);
2039 } 2119 }
2040 2120
2121 if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT &&
2122 !(readl(phba->HCregaddr) & HC_MBINT_ENA)) {
2123 spin_unlock_irqrestore(phba->host->host_lock, drvr_flag);
2124 LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag)
2125 return (MBX_NOT_FINISHED);
2126 }
2127
2041 if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { 2128 if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) {
2042 /* Polling for a mbox command when another one is already active 2129 /* Polling for a mbox command when another one is already active
2043 * is not allowed in SLI. Also, the driver must have established 2130 * is not allowed in SLI. Also, the driver must have established
@@ -2154,8 +2241,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
2154 /* First copy command data to host SLIM area */ 2241 /* First copy command data to host SLIM area */
2155 lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, MAILBOX_CMD_SIZE); 2242 lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, MAILBOX_CMD_SIZE);
2156 } else { 2243 } else {
2157 if (mb->mbxCommand == MBX_CONFIG_PORT || 2244 if (mb->mbxCommand == MBX_CONFIG_PORT) {
2158 mb->mbxCommand == MBX_KILL_BOARD) {
2159 /* copy command data into host mbox for cmpl */ 2245 /* copy command data into host mbox for cmpl */
2160 lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, 2246 lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx,
2161 MAILBOX_CMD_SIZE); 2247 MAILBOX_CMD_SIZE);
@@ -3121,6 +3207,7 @@ lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs)
3121 /* Clear Chip error bit */ 3207 /* Clear Chip error bit */
3122 writel(HA_ERATT, phba->HAregaddr); 3208 writel(HA_ERATT, phba->HAregaddr);
3123 readl(phba->HAregaddr); /* flush */ 3209 readl(phba->HAregaddr); /* flush */
3210 phba->stopped = 1;
3124 } 3211 }
3125 3212
3126 spin_lock(phba->host->host_lock); 3213 spin_lock(phba->host->host_lock);