aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2011-03-11 16:06:12 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-03-23 12:36:09 -0400
commit9940b97bb30d7435c881418c809ed652eb329583 (patch)
treed274c01b97553711c10f0d862b460aa3cd00ba02 /drivers/scsi
parent7f86059ac016d8662e5fbfab4875529510977b47 (diff)
[SCSI] lpfc 8.3.22: Add support for PCI Adapter Failure
Periodically poll adapter registers to detect pci adapter failure (reads return -1). On failure, take port offline, set error indicators and wake up worker threads. Threads will take adapter offline. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc.h25
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c10
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.c16
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c3
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c38
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c184
7 files changed, 207 insertions, 71 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index d9869f417d4..60e98a62f30 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -897,7 +897,18 @@ lpfc_worker_wake_up(struct lpfc_hba *phba)
897 return; 897 return;
898} 898}
899 899
900static inline void 900static inline int
901lpfc_readl(void __iomem *addr, uint32_t *data)
902{
903 uint32_t temp;
904 temp = readl(addr);
905 if (temp == 0xffffffff)
906 return -EIO;
907 *data = temp;
908 return 0;
909}
910
911static inline int
901lpfc_sli_read_hs(struct lpfc_hba *phba) 912lpfc_sli_read_hs(struct lpfc_hba *phba)
902{ 913{
903 /* 914 /*
@@ -906,15 +917,17 @@ lpfc_sli_read_hs(struct lpfc_hba *phba)
906 */ 917 */
907 phba->sli.slistat.err_attn_event++; 918 phba->sli.slistat.err_attn_event++;
908 919
909 /* Save status info */ 920 /* Save status info and check for unplug error */
910 phba->work_hs = readl(phba->HSregaddr); 921 if (lpfc_readl(phba->HSregaddr, &phba->work_hs) ||
911 phba->work_status[0] = readl(phba->MBslimaddr + 0xa8); 922 lpfc_readl(phba->MBslimaddr + 0xa8, &phba->work_status[0]) ||
912 phba->work_status[1] = readl(phba->MBslimaddr + 0xac); 923 lpfc_readl(phba->MBslimaddr + 0xac, &phba->work_status[1])) {
924 return -EIO;
925 }
913 926
914 /* Clear chip Host Attention error bit */ 927 /* Clear chip Host Attention error bit */
915 writel(HA_ERATT, phba->HAregaddr); 928 writel(HA_ERATT, phba->HAregaddr);
916 readl(phba->HAregaddr); /* flush */ 929 readl(phba->HAregaddr); /* flush */
917 phba->pport->stopped = 1; 930 phba->pport->stopped = 1;
918 931
919 return; 932 return 0;
920} 933}
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 427c046e820..4e0faa00b96 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1224,7 +1224,10 @@ lpfc_poll_store(struct device *dev, struct device_attribute *attr,
1224 if (val & ENABLE_FCP_RING_POLLING) { 1224 if (val & ENABLE_FCP_RING_POLLING) {
1225 if ((val & DISABLE_FCP_RING_INT) && 1225 if ((val & DISABLE_FCP_RING_INT) &&
1226 !(old_val & DISABLE_FCP_RING_INT)) { 1226 !(old_val & DISABLE_FCP_RING_INT)) {
1227 creg_val = readl(phba->HCregaddr); 1227 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
1228 spin_unlock_irq(&phba->hbalock);
1229 return -EINVAL;
1230 }
1228 creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING); 1231 creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
1229 writel(creg_val, phba->HCregaddr); 1232 writel(creg_val, phba->HCregaddr);
1230 readl(phba->HCregaddr); /* flush */ 1233 readl(phba->HCregaddr); /* flush */
@@ -1242,7 +1245,10 @@ lpfc_poll_store(struct device *dev, struct device_attribute *attr,
1242 spin_unlock_irq(&phba->hbalock); 1245 spin_unlock_irq(&phba->hbalock);
1243 del_timer(&phba->fcp_poll_timer); 1246 del_timer(&phba->fcp_poll_timer);
1244 spin_lock_irq(&phba->hbalock); 1247 spin_lock_irq(&phba->hbalock);
1245 creg_val = readl(phba->HCregaddr); 1248 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
1249 spin_unlock_irq(&phba->hbalock);
1250 return -EINVAL;
1251 }
1246 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING); 1252 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
1247 writel(creg_val, phba->HCregaddr); 1253 writel(creg_val, phba->HCregaddr);
1248 readl(phba->HCregaddr); /* flush */ 1254 readl(phba->HCregaddr); /* flush */
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 5a4a2f36ae6..d9b91b3f942 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -348,7 +348,10 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
348 dd_data->context_un.iocb.bmp = bmp; 348 dd_data->context_un.iocb.bmp = bmp;
349 349
350 if (phba->cfg_poll & DISABLE_FCP_RING_INT) { 350 if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
351 creg_val = readl(phba->HCregaddr); 351 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
352 rc = -EIO ;
353 goto free_cmdiocbq;
354 }
352 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING); 355 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
353 writel(creg_val, phba->HCregaddr); 356 writel(creg_val, phba->HCregaddr);
354 readl(phba->HCregaddr); /* flush */ 357 readl(phba->HCregaddr); /* flush */
@@ -599,7 +602,10 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
599 dd_data->context_un.iocb.ndlp = ndlp; 602 dd_data->context_un.iocb.ndlp = ndlp;
600 603
601 if (phba->cfg_poll & DISABLE_FCP_RING_INT) { 604 if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
602 creg_val = readl(phba->HCregaddr); 605 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
606 rc = -EIO;
607 goto linkdown_err;
608 }
603 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING); 609 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
604 writel(creg_val, phba->HCregaddr); 610 writel(creg_val, phba->HCregaddr);
605 readl(phba->HCregaddr); /* flush */ 611 readl(phba->HCregaddr); /* flush */
@@ -613,6 +619,7 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
613 else 619 else
614 rc = -EIO; 620 rc = -EIO;
615 621
622linkdown_err:
616 pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, 623 pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
617 job->request_payload.sg_cnt, DMA_TO_DEVICE); 624 job->request_payload.sg_cnt, DMA_TO_DEVICE);
618 pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list, 625 pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
@@ -1357,7 +1364,10 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag,
1357 dd_data->context_un.iocb.ndlp = ndlp; 1364 dd_data->context_un.iocb.ndlp = ndlp;
1358 1365
1359 if (phba->cfg_poll & DISABLE_FCP_RING_INT) { 1366 if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
1360 creg_val = readl(phba->HCregaddr); 1367 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
1368 rc = -IOCB_ERROR;
1369 goto issue_ct_rsp_exit;
1370 }
1361 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING); 1371 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
1362 writel(creg_val, phba->HCregaddr); 1372 writel(creg_val, phba->HCregaddr);
1363 readl(phba->HCregaddr); /* flush */ 1373 readl(phba->HCregaddr); /* flush */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 8e28edf9801..735028fedda 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -89,7 +89,8 @@ lpfc_els_chk_latt(struct lpfc_vport *vport)
89 return 0; 89 return 0;
90 90
91 /* Read the HBA Host Attention Register */ 91 /* Read the HBA Host Attention Register */
92 ha_copy = readl(phba->HAregaddr); 92 if (lpfc_readl(phba->HAregaddr, &ha_copy))
93 return 1;
93 94
94 if (!(ha_copy & HA_LATT)) 95 if (!(ha_copy & HA_LATT))
95 return 0; 96 return 0;
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 057ab82bf39..c3a0e62de49 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1344,7 +1344,7 @@ typedef struct { /* FireFly BIU registers */
1344#define HS_FFER1 0x80000000 /* Bit 31 */ 1344#define HS_FFER1 0x80000000 /* Bit 31 */
1345#define HS_CRIT_TEMP 0x00000100 /* Bit 8 */ 1345#define HS_CRIT_TEMP 0x00000100 /* Bit 8 */
1346#define HS_FFERM 0xFF000100 /* Mask for error bits 31:24 and 8 */ 1346#define HS_FFERM 0xFF000100 /* Mask for error bits 31:24 and 8 */
1347 1347#define UNPLUG_ERR 0x00000001 /* Indicate pci hot unplug */
1348/* Host Control Register */ 1348/* Host Control Register */
1349 1349
1350#define HC_REG_OFFSET 12 /* Byte offset from register base address */ 1350#define HC_REG_OFFSET 12 /* Byte offset from register base address */
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 29aab9432af..d5d07a890b6 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -507,7 +507,10 @@ lpfc_config_port_post(struct lpfc_hba *phba)
507 phba->hba_flag &= ~HBA_ERATT_HANDLED; 507 phba->hba_flag &= ~HBA_ERATT_HANDLED;
508 508
509 /* Enable appropriate host interrupts */ 509 /* Enable appropriate host interrupts */
510 status = readl(phba->HCregaddr); 510 if (lpfc_readl(phba->HCregaddr, &status)) {
511 spin_unlock_irq(&phba->hbalock);
512 return -EIO;
513 }
511 status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA; 514 status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA;
512 if (psli->num_rings > 0) 515 if (psli->num_rings > 0)
513 status |= HC_R0INT_ENA; 516 status |= HC_R0INT_ENA;
@@ -1222,7 +1225,10 @@ lpfc_handle_deferred_eratt(struct lpfc_hba *phba)
1222 /* Wait for the ER1 bit to clear.*/ 1225 /* Wait for the ER1 bit to clear.*/
1223 while (phba->work_hs & HS_FFER1) { 1226 while (phba->work_hs & HS_FFER1) {
1224 msleep(100); 1227 msleep(100);
1225 phba->work_hs = readl(phba->HSregaddr); 1228 if (lpfc_readl(phba->HSregaddr, &phba->work_hs)) {
1229 phba->work_hs = UNPLUG_ERR ;
1230 break;
1231 }
1226 /* If driver is unloading let the worker thread continue */ 1232 /* If driver is unloading let the worker thread continue */
1227 if (phba->pport->load_flag & FC_UNLOADING) { 1233 if (phba->pport->load_flag & FC_UNLOADING) {
1228 phba->work_hs = 0; 1234 phba->work_hs = 0;
@@ -5386,13 +5392,16 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
5386 int i, port_error = 0; 5392 int i, port_error = 0;
5387 uint32_t if_type; 5393 uint32_t if_type;
5388 5394
5395 memset(&portsmphr_reg, 0, sizeof(portsmphr_reg));
5396 memset(&reg_data, 0, sizeof(reg_data));
5389 if (!phba->sli4_hba.PSMPHRregaddr) 5397 if (!phba->sli4_hba.PSMPHRregaddr)
5390 return -ENODEV; 5398 return -ENODEV;
5391 5399
5392 /* Wait up to 30 seconds for the SLI Port POST done and ready */ 5400 /* Wait up to 30 seconds for the SLI Port POST done and ready */
5393 for (i = 0; i < 3000; i++) { 5401 for (i = 0; i < 3000; i++) {
5394 portsmphr_reg.word0 = readl(phba->sli4_hba.PSMPHRregaddr); 5402 if (lpfc_readl(phba->sli4_hba.PSMPHRregaddr,
5395 if (bf_get(lpfc_port_smphr_perr, &portsmphr_reg)) { 5403 &portsmphr_reg.word0) ||
5404 (bf_get(lpfc_port_smphr_perr, &portsmphr_reg))) {
5396 /* Port has a fatal POST error, break out */ 5405 /* Port has a fatal POST error, break out */
5397 port_error = -ENODEV; 5406 port_error = -ENODEV;
5398 break; 5407 break;
@@ -5473,9 +5482,9 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
5473 break; 5482 break;
5474 case LPFC_SLI_INTF_IF_TYPE_2: 5483 case LPFC_SLI_INTF_IF_TYPE_2:
5475 /* Final checks. The port status should be clean. */ 5484 /* Final checks. The port status should be clean. */
5476 reg_data.word0 = 5485 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
5477 readl(phba->sli4_hba.u.if_type2.STATUSregaddr); 5486 &reg_data.word0) ||
5478 if (bf_get(lpfc_sliport_status_err, &reg_data)) { 5487 bf_get(lpfc_sliport_status_err, &reg_data)) {
5479 phba->work_status[0] = 5488 phba->work_status[0] =
5480 readl(phba->sli4_hba.u.if_type2. 5489 readl(phba->sli4_hba.u.if_type2.
5481 ERR1regaddr); 5490 ERR1regaddr);
@@ -6761,9 +6770,11 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
6761 * the loop again. 6770 * the loop again.
6762 */ 6771 */
6763 for (rdy_chk = 0; rdy_chk < 1000; rdy_chk++) { 6772 for (rdy_chk = 0; rdy_chk < 1000; rdy_chk++) {
6764 reg_data.word0 = 6773 if (lpfc_readl(phba->sli4_hba.u.if_type2.
6765 readl(phba->sli4_hba.u.if_type2. 6774 STATUSregaddr, &reg_data.word0)) {
6766 STATUSregaddr); 6775 rc = -ENODEV;
6776 break;
6777 }
6767 if (bf_get(lpfc_sliport_status_rdy, &reg_data)) 6778 if (bf_get(lpfc_sliport_status_rdy, &reg_data))
6768 break; 6779 break;
6769 if (bf_get(lpfc_sliport_status_rn, &reg_data)) { 6780 if (bf_get(lpfc_sliport_status_rn, &reg_data)) {
@@ -6784,8 +6795,11 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
6784 } 6795 }
6785 6796
6786 /* Detect any port errors. */ 6797 /* Detect any port errors. */
6787 reg_data.word0 = readl(phba->sli4_hba.u.if_type2. 6798 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
6788 STATUSregaddr); 6799 &reg_data.word0)) {
6800 rc = -ENODEV;
6801 break;
6802 }
6789 if ((bf_get(lpfc_sliport_status_err, &reg_data)) || 6803 if ((bf_get(lpfc_sliport_status_err, &reg_data)) ||
6790 (rdy_chk >= 1000)) { 6804 (rdy_chk >= 1000)) {
6791 phba->work_status[0] = readl( 6805 phba->work_status[0] = readl(
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 84234a4c54c..3218c184be6 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -3477,7 +3477,8 @@ lpfc_sli_brdready_s3(struct lpfc_hba *phba, uint32_t mask)
3477 int retval = 0; 3477 int retval = 0;
3478 3478
3479 /* Read the HBA Host Status Register */ 3479 /* Read the HBA Host Status Register */
3480 status = readl(phba->HSregaddr); 3480 if (lpfc_readl(phba->HSregaddr, &status))
3481 return 1;
3481 3482
3482 /* 3483 /*
3483 * Check status register every 100ms for 5 retries, then every 3484 * Check status register every 100ms for 5 retries, then every
@@ -3502,7 +3503,10 @@ lpfc_sli_brdready_s3(struct lpfc_hba *phba, uint32_t mask)
3502 lpfc_sli_brdrestart(phba); 3503 lpfc_sli_brdrestart(phba);
3503 } 3504 }
3504 /* Read the HBA Host Status Register */ 3505 /* Read the HBA Host Status Register */
3505 status = readl(phba->HSregaddr); 3506 if (lpfc_readl(phba->HSregaddr, &status)) {
3507 retval = 1;
3508 break;
3509 }
3506 } 3510 }
3507 3511
3508 /* Check to see if any errors occurred during init */ 3512 /* Check to see if any errors occurred during init */
@@ -3584,7 +3588,7 @@ void lpfc_reset_barrier(struct lpfc_hba *phba)
3584 uint32_t __iomem *resp_buf; 3588 uint32_t __iomem *resp_buf;
3585 uint32_t __iomem *mbox_buf; 3589 uint32_t __iomem *mbox_buf;
3586 volatile uint32_t mbox; 3590 volatile uint32_t mbox;
3587 uint32_t hc_copy; 3591 uint32_t hc_copy, ha_copy, resp_data;
3588 int i; 3592 int i;
3589 uint8_t hdrtype; 3593 uint8_t hdrtype;
3590 3594
@@ -3601,12 +3605,15 @@ void lpfc_reset_barrier(struct lpfc_hba *phba)
3601 resp_buf = phba->MBslimaddr; 3605 resp_buf = phba->MBslimaddr;
3602 3606
3603 /* Disable the error attention */ 3607 /* Disable the error attention */
3604 hc_copy = readl(phba->HCregaddr); 3608 if (lpfc_readl(phba->HCregaddr, &hc_copy))
3609 return;
3605 writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr); 3610 writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr);
3606 readl(phba->HCregaddr); /* flush */ 3611 readl(phba->HCregaddr); /* flush */
3607 phba->link_flag |= LS_IGNORE_ERATT; 3612 phba->link_flag |= LS_IGNORE_ERATT;
3608 3613
3609 if (readl(phba->HAregaddr) & HA_ERATT) { 3614 if (lpfc_readl(phba->HAregaddr, &ha_copy))
3615 return;
3616 if (ha_copy & HA_ERATT) {
3610 /* Clear Chip error bit */ 3617 /* Clear Chip error bit */
3611 writel(HA_ERATT, phba->HAregaddr); 3618 writel(HA_ERATT, phba->HAregaddr);
3612 phba->pport->stopped = 1; 3619 phba->pport->stopped = 1;
@@ -3620,11 +3627,18 @@ void lpfc_reset_barrier(struct lpfc_hba *phba)
3620 mbox_buf = phba->MBslimaddr; 3627 mbox_buf = phba->MBslimaddr;
3621 writel(mbox, mbox_buf); 3628 writel(mbox, mbox_buf);
3622 3629
3623 for (i = 0; 3630 for (i = 0; i < 50; i++) {
3624 readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN) && i < 50; i++) 3631 if (lpfc_readl((resp_buf + 1), &resp_data))
3625 mdelay(1); 3632 return;
3626 3633 if (resp_data != ~(BARRIER_TEST_PATTERN))
3627 if (readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN)) { 3634 mdelay(1);
3635 else
3636 break;
3637 }
3638 resp_data = 0;
3639 if (lpfc_readl((resp_buf + 1), &resp_data))
3640 return;
3641 if (resp_data != ~(BARRIER_TEST_PATTERN)) {
3628 if (phba->sli.sli_flag & LPFC_SLI_ACTIVE || 3642 if (phba->sli.sli_flag & LPFC_SLI_ACTIVE ||
3629 phba->pport->stopped) 3643 phba->pport->stopped)
3630 goto restore_hc; 3644 goto restore_hc;
@@ -3633,13 +3647,26 @@ void lpfc_reset_barrier(struct lpfc_hba *phba)
3633 } 3647 }
3634 3648
3635 ((MAILBOX_t *)&mbox)->mbxOwner = OWN_HOST; 3649 ((MAILBOX_t *)&mbox)->mbxOwner = OWN_HOST;
3636 for (i = 0; readl(resp_buf) != mbox && i < 500; i++) 3650 resp_data = 0;
3637 mdelay(1); 3651 for (i = 0; i < 500; i++) {
3652 if (lpfc_readl(resp_buf, &resp_data))
3653 return;
3654 if (resp_data != mbox)
3655 mdelay(1);
3656 else
3657 break;
3658 }
3638 3659
3639clear_errat: 3660clear_errat:
3640 3661
3641 while (!(readl(phba->HAregaddr) & HA_ERATT) && ++i < 500) 3662 while (++i < 500) {
3642 mdelay(1); 3663 if (lpfc_readl(phba->HAregaddr, &ha_copy))
3664 return;
3665 if (!(ha_copy & HA_ERATT))
3666 mdelay(1);
3667 else
3668 break;
3669 }
3643 3670
3644 if (readl(phba->HAregaddr) & HA_ERATT) { 3671 if (readl(phba->HAregaddr) & HA_ERATT) {
3645 writel(HA_ERATT, phba->HAregaddr); 3672 writel(HA_ERATT, phba->HAregaddr);
@@ -3686,7 +3713,11 @@ lpfc_sli_brdkill(struct lpfc_hba *phba)
3686 3713
3687 /* Disable the error attention */ 3714 /* Disable the error attention */
3688 spin_lock_irq(&phba->hbalock); 3715 spin_lock_irq(&phba->hbalock);
3689 status = readl(phba->HCregaddr); 3716 if (lpfc_readl(phba->HCregaddr, &status)) {
3717 spin_unlock_irq(&phba->hbalock);
3718 mempool_free(pmb, phba->mbox_mem_pool);
3719 return 1;
3720 }
3690 status &= ~HC_ERINT_ENA; 3721 status &= ~HC_ERINT_ENA;
3691 writel(status, phba->HCregaddr); 3722 writel(status, phba->HCregaddr);
3692 readl(phba->HCregaddr); /* flush */ 3723 readl(phba->HCregaddr); /* flush */
@@ -3720,11 +3751,12 @@ lpfc_sli_brdkill(struct lpfc_hba *phba)
3720 * 3 seconds we still set HBA_ERROR state because the status of the 3751 * 3 seconds we still set HBA_ERROR state because the status of the
3721 * board is now undefined. 3752 * board is now undefined.
3722 */ 3753 */
3723 ha_copy = readl(phba->HAregaddr); 3754 if (lpfc_readl(phba->HAregaddr, &ha_copy))
3724 3755 return 1;
3725 while ((i++ < 30) && !(ha_copy & HA_ERATT)) { 3756 while ((i++ < 30) && !(ha_copy & HA_ERATT)) {
3726 mdelay(100); 3757 mdelay(100);
3727 ha_copy = readl(phba->HAregaddr); 3758 if (lpfc_readl(phba->HAregaddr, &ha_copy))
3759 return 1;
3728 } 3760 }
3729 3761
3730 del_timer_sync(&psli->mbox_tmo); 3762 del_timer_sync(&psli->mbox_tmo);
@@ -4018,7 +4050,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
4018 uint32_t status, i = 0; 4050 uint32_t status, i = 0;
4019 4051
4020 /* Read the HBA Host Status Register */ 4052 /* Read the HBA Host Status Register */
4021 status = readl(phba->HSregaddr); 4053 if (lpfc_readl(phba->HSregaddr, &status))
4054 return -EIO;
4022 4055
4023 /* Check status register to see what current state is */ 4056 /* Check status register to see what current state is */
4024 i = 0; 4057 i = 0;
@@ -4073,7 +4106,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
4073 lpfc_sli_brdrestart(phba); 4106 lpfc_sli_brdrestart(phba);
4074 } 4107 }
4075 /* Read the HBA Host Status Register */ 4108 /* Read the HBA Host Status Register */
4076 status = readl(phba->HSregaddr); 4109 if (lpfc_readl(phba->HSregaddr, &status))
4110 return -EIO;
4077 } 4111 }
4078 4112
4079 /* Check to see if any errors occurred during init */ 4113 /* Check to see if any errors occurred during init */
@@ -5136,7 +5170,7 @@ lpfc_sli_issue_mbox_s3(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox,
5136 MAILBOX_t *mb; 5170 MAILBOX_t *mb;
5137 struct lpfc_sli *psli = &phba->sli; 5171 struct lpfc_sli *psli = &phba->sli;
5138 uint32_t status, evtctr; 5172 uint32_t status, evtctr;
5139 uint32_t ha_copy; 5173 uint32_t ha_copy, hc_copy;
5140 int i; 5174 int i;
5141 unsigned long timeout; 5175 unsigned long timeout;
5142 unsigned long drvr_flag = 0; 5176 unsigned long drvr_flag = 0;
@@ -5202,15 +5236,17 @@ lpfc_sli_issue_mbox_s3(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox,
5202 goto out_not_finished; 5236 goto out_not_finished;
5203 } 5237 }
5204 5238
5205 if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && 5239 if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT) {
5206 !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { 5240 if (lpfc_readl(phba->HCregaddr, &hc_copy) ||
5207 spin_unlock_irqrestore(&phba->hbalock, drvr_flag); 5241 !(hc_copy & HC_MBINT_ENA)) {
5208 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, 5242 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
5243 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
5209 "(%d):2528 Mailbox command x%x cannot " 5244 "(%d):2528 Mailbox command x%x cannot "
5210 "issue Data: x%x x%x\n", 5245 "issue Data: x%x x%x\n",
5211 pmbox->vport ? pmbox->vport->vpi : 0, 5246 pmbox->vport ? pmbox->vport->vpi : 0,
5212 pmbox->u.mb.mbxCommand, psli->sli_flag, flag); 5247 pmbox->u.mb.mbxCommand, psli->sli_flag, flag);
5213 goto out_not_finished; 5248 goto out_not_finished;
5249 }
5214 } 5250 }
5215 5251
5216 if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { 5252 if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) {
@@ -5408,11 +5444,19 @@ lpfc_sli_issue_mbox_s3(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox,
5408 word0 = le32_to_cpu(word0); 5444 word0 = le32_to_cpu(word0);
5409 } else { 5445 } else {
5410 /* First read mbox status word */ 5446 /* First read mbox status word */
5411 word0 = readl(phba->MBslimaddr); 5447 if (lpfc_readl(phba->MBslimaddr, &word0)) {
5448 spin_unlock_irqrestore(&phba->hbalock,
5449 drvr_flag);
5450 goto out_not_finished;
5451 }
5412 } 5452 }
5413 5453
5414 /* Read the HBA Host Attention Register */ 5454 /* Read the HBA Host Attention Register */
5415 ha_copy = readl(phba->HAregaddr); 5455 if (lpfc_readl(phba->HAregaddr, &ha_copy)) {
5456 spin_unlock_irqrestore(&phba->hbalock,
5457 drvr_flag);
5458 goto out_not_finished;
5459 }
5416 timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, 5460 timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba,
5417 mb->mbxCommand) * 5461 mb->mbxCommand) *
5418 1000) + jiffies; 5462 1000) + jiffies;
@@ -5463,7 +5507,11 @@ lpfc_sli_issue_mbox_s3(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox,
5463 word0 = readl(phba->MBslimaddr); 5507 word0 = readl(phba->MBslimaddr);
5464 } 5508 }
5465 /* Read the HBA Host Attention Register */ 5509 /* Read the HBA Host Attention Register */
5466 ha_copy = readl(phba->HAregaddr); 5510 if (lpfc_readl(phba->HAregaddr, &ha_copy)) {
5511 spin_unlock_irqrestore(&phba->hbalock,
5512 drvr_flag);
5513 goto out_not_finished;
5514 }
5467 } 5515 }
5468 5516
5469 if (psli->sli_flag & LPFC_SLI_ACTIVE) { 5517 if (psli->sli_flag & LPFC_SLI_ACTIVE) {
@@ -8194,7 +8242,8 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba,
8194 piocb->iocb_flag &= ~LPFC_IO_WAKE; 8242 piocb->iocb_flag &= ~LPFC_IO_WAKE;
8195 8243
8196 if (phba->cfg_poll & DISABLE_FCP_RING_INT) { 8244 if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
8197 creg_val = readl(phba->HCregaddr); 8245 if (lpfc_readl(phba->HCregaddr, &creg_val))
8246 return IOCB_ERROR;
8198 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING); 8247 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
8199 writel(creg_val, phba->HCregaddr); 8248 writel(creg_val, phba->HCregaddr);
8200 readl(phba->HCregaddr); /* flush */ 8249 readl(phba->HCregaddr); /* flush */
@@ -8236,7 +8285,8 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba,
8236 } 8285 }
8237 8286
8238 if (phba->cfg_poll & DISABLE_FCP_RING_INT) { 8287 if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
8239 creg_val = readl(phba->HCregaddr); 8288 if (lpfc_readl(phba->HCregaddr, &creg_val))
8289 return IOCB_ERROR;
8240 creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING); 8290 creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
8241 writel(creg_val, phba->HCregaddr); 8291 writel(creg_val, phba->HCregaddr);
8242 readl(phba->HCregaddr); /* flush */ 8292 readl(phba->HCregaddr); /* flush */
@@ -8387,10 +8437,13 @@ lpfc_sli_eratt_read(struct lpfc_hba *phba)
8387 uint32_t ha_copy; 8437 uint32_t ha_copy;
8388 8438
8389 /* Read chip Host Attention (HA) register */ 8439 /* Read chip Host Attention (HA) register */
8390 ha_copy = readl(phba->HAregaddr); 8440 if (lpfc_readl(phba->HAregaddr, &ha_copy))
8441 goto unplug_err;
8442
8391 if (ha_copy & HA_ERATT) { 8443 if (ha_copy & HA_ERATT) {
8392 /* Read host status register to retrieve error event */ 8444 /* Read host status register to retrieve error event */
8393 lpfc_sli_read_hs(phba); 8445 if (lpfc_sli_read_hs(phba))
8446 goto unplug_err;
8394 8447
8395 /* Check if there is a deferred error condition is active */ 8448 /* Check if there is a deferred error condition is active */
8396 if ((HS_FFER1 & phba->work_hs) && 8449 if ((HS_FFER1 & phba->work_hs) &&
@@ -8409,6 +8462,15 @@ lpfc_sli_eratt_read(struct lpfc_hba *phba)
8409 return 1; 8462 return 1;
8410 } 8463 }
8411 return 0; 8464 return 0;
8465
8466unplug_err:
8467 /* Set the driver HS work bitmap */
8468 phba->work_hs |= UNPLUG_ERR;
8469 /* Set the driver HA work bitmap */
8470 phba->work_ha |= HA_ERATT;
8471 /* Indicate polling handles this ERATT */
8472 phba->hba_flag |= HBA_ERATT_HANDLED;
8473 return 1;
8412} 8474}
8413 8475
8414/** 8476/**
@@ -8436,8 +8498,15 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba)
8436 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); 8498 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
8437 switch (if_type) { 8499 switch (if_type) {
8438 case LPFC_SLI_INTF_IF_TYPE_0: 8500 case LPFC_SLI_INTF_IF_TYPE_0:
8439 uerr_sta_lo = readl(phba->sli4_hba.u.if_type0.UERRLOregaddr); 8501 if (lpfc_readl(phba->sli4_hba.u.if_type0.UERRLOregaddr,
8440 uerr_sta_hi = readl(phba->sli4_hba.u.if_type0.UERRHIregaddr); 8502 &uerr_sta_lo) ||
8503 lpfc_readl(phba->sli4_hba.u.if_type0.UERRHIregaddr,
8504 &uerr_sta_hi)) {
8505 phba->work_hs |= UNPLUG_ERR;
8506 phba->work_ha |= HA_ERATT;
8507 phba->hba_flag |= HBA_ERATT_HANDLED;
8508 return 1;
8509 }
8441 if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) || 8510 if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) ||
8442 (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) { 8511 (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) {
8443 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 8512 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -8456,9 +8525,15 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba)
8456 } 8525 }
8457 break; 8526 break;
8458 case LPFC_SLI_INTF_IF_TYPE_2: 8527 case LPFC_SLI_INTF_IF_TYPE_2:
8459 portstat_reg.word0 = 8528 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
8460 readl(phba->sli4_hba.u.if_type2.STATUSregaddr); 8529 &portstat_reg.word0) ||
8461 portsmphr = readl(phba->sli4_hba.PSMPHRregaddr); 8530 lpfc_readl(phba->sli4_hba.PSMPHRregaddr,
8531 &portsmphr)){
8532 phba->work_hs |= UNPLUG_ERR;
8533 phba->work_ha |= HA_ERATT;
8534 phba->hba_flag |= HBA_ERATT_HANDLED;
8535 return 1;
8536 }
8462 if (bf_get(lpfc_sliport_status_err, &portstat_reg)) { 8537 if (bf_get(lpfc_sliport_status_err, &portstat_reg)) {
8463 phba->work_status[0] = 8538 phba->work_status[0] =
8464 readl(phba->sli4_hba.u.if_type2.ERR1regaddr); 8539 readl(phba->sli4_hba.u.if_type2.ERR1regaddr);
@@ -8639,7 +8714,8 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id)
8639 return IRQ_NONE; 8714 return IRQ_NONE;
8640 /* Need to read HA REG for slow-path events */ 8715 /* Need to read HA REG for slow-path events */
8641 spin_lock_irqsave(&phba->hbalock, iflag); 8716 spin_lock_irqsave(&phba->hbalock, iflag);
8642 ha_copy = readl(phba->HAregaddr); 8717 if (lpfc_readl(phba->HAregaddr, &ha_copy))
8718 goto unplug_error;
8643 /* If somebody is waiting to handle an eratt don't process it 8719 /* If somebody is waiting to handle an eratt don't process it
8644 * here. The brdkill function will do this. 8720 * here. The brdkill function will do this.
8645 */ 8721 */
@@ -8665,7 +8741,9 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id)
8665 } 8741 }
8666 8742
8667 /* Clear up only attention source related to slow-path */ 8743 /* Clear up only attention source related to slow-path */
8668 hc_copy = readl(phba->HCregaddr); 8744 if (lpfc_readl(phba->HCregaddr, &hc_copy))
8745 goto unplug_error;
8746
8669 writel(hc_copy & ~(HC_MBINT_ENA | HC_R2INT_ENA | 8747 writel(hc_copy & ~(HC_MBINT_ENA | HC_R2INT_ENA |
8670 HC_LAINT_ENA | HC_ERINT_ENA), 8748 HC_LAINT_ENA | HC_ERINT_ENA),
8671 phba->HCregaddr); 8749 phba->HCregaddr);
@@ -8688,7 +8766,8 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id)
8688 */ 8766 */
8689 spin_lock_irqsave(&phba->hbalock, iflag); 8767 spin_lock_irqsave(&phba->hbalock, iflag);
8690 phba->sli.sli_flag &= ~LPFC_PROCESS_LA; 8768 phba->sli.sli_flag &= ~LPFC_PROCESS_LA;
8691 control = readl(phba->HCregaddr); 8769 if (lpfc_readl(phba->HCregaddr, &control))
8770 goto unplug_error;
8692 control &= ~HC_LAINT_ENA; 8771 control &= ~HC_LAINT_ENA;
8693 writel(control, phba->HCregaddr); 8772 writel(control, phba->HCregaddr);
8694 readl(phba->HCregaddr); /* flush */ 8773 readl(phba->HCregaddr); /* flush */
@@ -8708,7 +8787,8 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id)
8708 status >>= (4*LPFC_ELS_RING); 8787 status >>= (4*LPFC_ELS_RING);
8709 if (status & HA_RXMASK) { 8788 if (status & HA_RXMASK) {
8710 spin_lock_irqsave(&phba->hbalock, iflag); 8789 spin_lock_irqsave(&phba->hbalock, iflag);
8711 control = readl(phba->HCregaddr); 8790 if (lpfc_readl(phba->HCregaddr, &control))
8791 goto unplug_error;
8712 8792
8713 lpfc_debugfs_slow_ring_trc(phba, 8793 lpfc_debugfs_slow_ring_trc(phba,
8714 "ISR slow ring: ctl:x%x stat:x%x isrcnt:x%x", 8794 "ISR slow ring: ctl:x%x stat:x%x isrcnt:x%x",
@@ -8741,7 +8821,8 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id)
8741 } 8821 }
8742 spin_lock_irqsave(&phba->hbalock, iflag); 8822 spin_lock_irqsave(&phba->hbalock, iflag);
8743 if (work_ha_copy & HA_ERATT) { 8823 if (work_ha_copy & HA_ERATT) {
8744 lpfc_sli_read_hs(phba); 8824 if (lpfc_sli_read_hs(phba))
8825 goto unplug_error;
8745 /* 8826 /*
8746 * Check if there is a deferred error condition 8827 * Check if there is a deferred error condition
8747 * is active 8828 * is active
@@ -8872,6 +8953,9 @@ send_current_mbox:
8872 lpfc_worker_wake_up(phba); 8953 lpfc_worker_wake_up(phba);
8873 } 8954 }
8874 return IRQ_HANDLED; 8955 return IRQ_HANDLED;
8956unplug_error:
8957 spin_unlock_irqrestore(&phba->hbalock, iflag);
8958 return IRQ_HANDLED;
8875 8959
8876} /* lpfc_sli_sp_intr_handler */ 8960} /* lpfc_sli_sp_intr_handler */
8877 8961
@@ -8919,7 +9003,8 @@ lpfc_sli_fp_intr_handler(int irq, void *dev_id)
8919 if (lpfc_intr_state_check(phba)) 9003 if (lpfc_intr_state_check(phba))
8920 return IRQ_NONE; 9004 return IRQ_NONE;
8921 /* Need to read HA REG for FCP ring and other ring events */ 9005 /* Need to read HA REG for FCP ring and other ring events */
8922 ha_copy = readl(phba->HAregaddr); 9006 if (lpfc_readl(phba->HAregaddr, &ha_copy))
9007 return IRQ_HANDLED;
8923 /* Clear up only attention source related to fast-path */ 9008 /* Clear up only attention source related to fast-path */
8924 spin_lock_irqsave(&phba->hbalock, iflag); 9009 spin_lock_irqsave(&phba->hbalock, iflag);
8925 /* 9010 /*
@@ -9004,7 +9089,11 @@ lpfc_sli_intr_handler(int irq, void *dev_id)
9004 return IRQ_NONE; 9089 return IRQ_NONE;
9005 9090
9006 spin_lock(&phba->hbalock); 9091 spin_lock(&phba->hbalock);
9007 phba->ha_copy = readl(phba->HAregaddr); 9092 if (lpfc_readl(phba->HAregaddr, &phba->ha_copy)) {
9093 spin_unlock(&phba->hbalock);
9094 return IRQ_HANDLED;
9095 }
9096
9008 if (unlikely(!phba->ha_copy)) { 9097 if (unlikely(!phba->ha_copy)) {
9009 spin_unlock(&phba->hbalock); 9098 spin_unlock(&phba->hbalock);
9010 return IRQ_NONE; 9099 return IRQ_NONE;
@@ -9026,7 +9115,10 @@ lpfc_sli_intr_handler(int irq, void *dev_id)
9026 } 9115 }
9027 9116
9028 /* Clear attention sources except link and error attentions */ 9117 /* Clear attention sources except link and error attentions */
9029 hc_copy = readl(phba->HCregaddr); 9118 if (lpfc_readl(phba->HCregaddr, &hc_copy)) {
9119 spin_unlock(&phba->hbalock);
9120 return IRQ_HANDLED;
9121 }
9030 writel(hc_copy & ~(HC_MBINT_ENA | HC_R0INT_ENA | HC_R1INT_ENA 9122 writel(hc_copy & ~(HC_MBINT_ENA | HC_R0INT_ENA | HC_R1INT_ENA
9031 | HC_R2INT_ENA | HC_LAINT_ENA | HC_ERINT_ENA), 9123 | HC_R2INT_ENA | HC_LAINT_ENA | HC_ERINT_ENA),
9032 phba->HCregaddr); 9124 phba->HCregaddr);