aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c10
-rw-r--r--drivers/scsi/be2iscsi/be_main.c26
-rw-r--r--drivers/scsi/be2iscsi/be_main.h5
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c132
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h7
5 files changed, 178 insertions, 2 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 352fc53e91b8..5c87768c109c 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -157,6 +157,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
157 struct be_cmd_req_hdr *ioctl_hdr; 157 struct be_cmd_req_hdr *ioctl_hdr;
158 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 158 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
159 159
160 if (beiscsi_error(phba))
161 return -EIO;
162
160 /* wait for the mccq completion */ 163 /* wait for the mccq completion */
161 rc = wait_event_interruptible_timeout( 164 rc = wait_event_interruptible_timeout(
162 phba->ctrl.mcc_wait[tag], 165 phba->ctrl.mcc_wait[tag],
@@ -423,7 +426,7 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba)
423{ 426{
424 int i, status; 427 int i, status;
425 for (i = 0; i < mcc_timeout; i++) { 428 for (i = 0; i < mcc_timeout; i++) {
426 if (phba->fw_timeout) 429 if (beiscsi_error(phba))
427 return -EIO; 430 return -EIO;
428 431
429 status = beiscsi_process_mcc(phba); 432 status = beiscsi_process_mcc(phba);
@@ -439,6 +442,7 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba)
439 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 442 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
440 "BC_%d : FW Timed Out\n"); 443 "BC_%d : FW Timed Out\n");
441 phba->fw_timeout = true; 444 phba->fw_timeout = true;
445 beiscsi_ue_detect(phba);
442 return -EBUSY; 446 return -EBUSY;
443 } 447 }
444 return 0; 448 return 0;
@@ -479,7 +483,8 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
479 u32 ready; 483 u32 ready;
480 484
481 do { 485 do {
482 if (phba->fw_timeout) 486
487 if (beiscsi_error(phba))
483 return -EIO; 488 return -EIO;
484 489
485 ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK; 490 ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
@@ -491,6 +496,7 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
491 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 496 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
492 "BC_%d : FW Timed Out\n"); 497 "BC_%d : FW Timed Out\n");
493 phba->fw_timeout = true; 498 phba->fw_timeout = true;
499 beiscsi_ue_detect(phba);
494 return -EBUSY; 500 return -EBUSY;
495 } 501 }
496 502
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 73a29b2c18ba..48d37dded8f1 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -4717,6 +4717,8 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba)
4717 phba->ctrl.mbox_mem_alloced.size, 4717 phba->ctrl.mbox_mem_alloced.size,
4718 phba->ctrl.mbox_mem_alloced.va, 4718 phba->ctrl.mbox_mem_alloced.va,
4719 phba->ctrl.mbox_mem_alloced.dma); 4719 phba->ctrl.mbox_mem_alloced.dma);
4720
4721 cancel_delayed_work_sync(&phba->beiscsi_hw_check_task);
4720} 4722}
4721 4723
4722static void beiscsi_remove(struct pci_dev *pcidev) 4724static void beiscsi_remove(struct pci_dev *pcidev)
@@ -4769,6 +4771,25 @@ static void beiscsi_msix_enable(struct beiscsi_hba *phba)
4769 return; 4771 return;
4770} 4772}
4771 4773
4774/*
4775 * beiscsi_hw_health_check()- Check adapter health
4776 * @work: work item to check HW health
4777 *
4778 * Check if adapter in an unrecoverable state or not.
4779 **/
4780static void
4781beiscsi_hw_health_check(struct work_struct *work)
4782{
4783 struct beiscsi_hba *phba =
4784 container_of(work, struct beiscsi_hba,
4785 beiscsi_hw_check_task.work);
4786
4787 beiscsi_ue_detect(phba);
4788
4789 schedule_delayed_work(&phba->beiscsi_hw_check_task,
4790 msecs_to_jiffies(1000));
4791}
4792
4772static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, 4793static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
4773 const struct pci_device_id *id) 4794 const struct pci_device_id *id)
4774{ 4795{
@@ -4892,6 +4913,8 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
4892 goto free_twq; 4913 goto free_twq;
4893 } 4914 }
4894 4915
4916 INIT_DELAYED_WORK(&phba->beiscsi_hw_check_task,
4917 beiscsi_hw_health_check);
4895 4918
4896 phwi_ctrlr = phba->phwi_ctrlr; 4919 phwi_ctrlr = phba->phwi_ctrlr;
4897 phwi_context = phwi_ctrlr->phwi_ctxt; 4920 phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -4941,6 +4964,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
4941 "iSCSI boot info.\n"); 4964 "iSCSI boot info.\n");
4942 4965
4943 beiscsi_create_def_ifaces(phba); 4966 beiscsi_create_def_ifaces(phba);
4967 schedule_delayed_work(&phba->beiscsi_hw_check_task,
4968 msecs_to_jiffies(1000));
4969
4944 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, 4970 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
4945 "\n\n\n BM_%d : SUCCESS - DRIVER LOADED\n\n\n"); 4971 "\n\n\n BM_%d : SUCCESS - DRIVER LOADED\n\n\n");
4946 return 0; 4972 return 0;
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 033c053d9471..5b27275cc811 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -750,6 +750,11 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
750 750
751void beiscsi_process_all_cqs(struct work_struct *work); 751void beiscsi_process_all_cqs(struct work_struct *work);
752 752
753static inline bool beiscsi_error(struct beiscsi_hba *phba)
754{
755 return phba->ue_detected || phba->fw_timeout;
756}
757
753struct pdu_nop_out { 758struct pdu_nop_out {
754 u32 dw[12]; 759 u32 dw[12];
755}; 760};
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 688bf64741e5..a6c2fe4b4d65 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -22,6 +22,138 @@
22#include <scsi/scsi_bsg_iscsi.h> 22#include <scsi/scsi_bsg_iscsi.h>
23#include "be_mgmt.h" 23#include "be_mgmt.h"
24#include "be_iscsi.h" 24#include "be_iscsi.h"
25#include "be_main.h"
26
27/* UE Status Low CSR */
28static const char * const desc_ue_status_low[] = {
29 "CEV",
30 "CTX",
31 "DBUF",
32 "ERX",
33 "Host",
34 "MPU",
35 "NDMA",
36 "PTC ",
37 "RDMA ",
38 "RXF ",
39 "RXIPS ",
40 "RXULP0 ",
41 "RXULP1 ",
42 "RXULP2 ",
43 "TIM ",
44 "TPOST ",
45 "TPRE ",
46 "TXIPS ",
47 "TXULP0 ",
48 "TXULP1 ",
49 "UC ",
50 "WDMA ",
51 "TXULP2 ",
52 "HOST1 ",
53 "P0_OB_LINK ",
54 "P1_OB_LINK ",
55 "HOST_GPIO ",
56 "MBOX ",
57 "AXGMAC0",
58 "AXGMAC1",
59 "JTAG",
60 "MPU_INTPEND"
61};
62
63/* UE Status High CSR */
64static const char * const desc_ue_status_hi[] = {
65 "LPCMEMHOST",
66 "MGMT_MAC",
67 "PCS0ONLINE",
68 "MPU_IRAM",
69 "PCS1ONLINE",
70 "PCTL0",
71 "PCTL1",
72 "PMEM",
73 "RR",
74 "TXPB",
75 "RXPP",
76 "XAUI",
77 "TXP",
78 "ARM",
79 "IPC",
80 "HOST2",
81 "HOST3",
82 "HOST4",
83 "HOST5",
84 "HOST6",
85 "HOST7",
86 "HOST8",
87 "HOST9",
88 "NETC",
89 "Unknown",
90 "Unknown",
91 "Unknown",
92 "Unknown",
93 "Unknown",
94 "Unknown",
95 "Unknown",
96 "Unknown"
97};
98
99/*
100 * beiscsi_ue_detec()- Detect Unrecoverable Error on adapter
101 * @phba: Driver priv structure
102 *
103 * Read registers linked to UE and check for the UE status
104 **/
105void beiscsi_ue_detect(struct beiscsi_hba *phba)
106{
107 uint32_t ue_hi = 0, ue_lo = 0;
108 uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
109 uint8_t i = 0;
110
111 if (phba->ue_detected)
112 return;
113
114 pci_read_config_dword(phba->pcidev,
115 PCICFG_UE_STATUS_LOW, &ue_lo);
116 pci_read_config_dword(phba->pcidev,
117 PCICFG_UE_STATUS_MASK_LOW,
118 &ue_mask_lo);
119 pci_read_config_dword(phba->pcidev,
120 PCICFG_UE_STATUS_HIGH,
121 &ue_hi);
122 pci_read_config_dword(phba->pcidev,
123 PCICFG_UE_STATUS_MASK_HI,
124 &ue_mask_hi);
125
126 ue_lo = (ue_lo & ~ue_mask_lo);
127 ue_hi = (ue_hi & ~ue_mask_hi);
128
129
130 if (ue_lo || ue_hi) {
131 phba->ue_detected = true;
132 beiscsi_log(phba, KERN_ERR,
133 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
134 "BG_%d : Error detected on the adapter\n");
135 }
136
137 if (ue_lo) {
138 for (i = 0; ue_lo; ue_lo >>= 1, i++) {
139 if (ue_lo & 1)
140 beiscsi_log(phba, KERN_ERR,
141 BEISCSI_LOG_CONFIG,
142 "BG_%d : UE_LOW %s bit set\n",
143 desc_ue_status_low[i]);
144 }
145 }
146
147 if (ue_hi) {
148 for (i = 0; ue_hi; ue_hi >>= 1, i++) {
149 if (ue_hi & 1)
150 beiscsi_log(phba, KERN_ERR,
151 BEISCSI_LOG_CONFIG,
152 "BG_%d : UE_HIGH %s bit set\n",
153 desc_ue_status_hi[i]);
154 }
155 }
156}
25 157
26/** 158/**
27 * mgmt_reopen_session()- Reopen a session based on reopen_type 159 * mgmt_reopen_session()- Reopen a session based on reopen_type
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 88a8ed21d7f6..2e4968add799 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -30,6 +30,12 @@
30#define IP_V6_LEN 16 30#define IP_V6_LEN 16
31#define IP_V4_LEN 4 31#define IP_V4_LEN 4
32 32
33/* UE Status and Mask register */
34#define PCICFG_UE_STATUS_LOW 0xA0
35#define PCICFG_UE_STATUS_HIGH 0xA4
36#define PCICFG_UE_STATUS_MASK_LOW 0xA8
37#define PCICFG_UE_STATUS_MASK_HI 0xAC
38
33/** 39/**
34 * Pseudo amap definition in which each bit of the actual structure is defined 40 * Pseudo amap definition in which each bit of the actual structure is defined
35 * as a byte: used to calculate offset/shift/mask of each field 41 * as a byte: used to calculate offset/shift/mask of each field
@@ -314,5 +320,6 @@ void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
314 320
315void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params, 321void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
316 struct wrb_handle *pwrb_handle); 322 struct wrb_handle *pwrb_handle);
323void beiscsi_ue_detect(struct beiscsi_hba *phba);
317 324
318#endif 325#endif