Commit 7a158003 authored by John Soni Jose's avatar John Soni Jose Committed by James Bottomley

[SCSI] be2iscsi: Fix Unrecoverable Error Detection

Driver periodically checks adapter state,is up fine or not.
Based on the value updates the internal structures of driver.
Signed-off-by: default avatarJohn Soni Jose <sony.john-n@emulex.com>
Signed-off-by: default avatarJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent e175defe
......@@ -157,6 +157,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
struct be_cmd_req_hdr *ioctl_hdr;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
if (beiscsi_error(phba))
return -EIO;
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
phba->ctrl.mcc_wait[tag],
......@@ -423,7 +426,7 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba)
{
int i, status;
for (i = 0; i < mcc_timeout; i++) {
if (phba->fw_timeout)
if (beiscsi_error(phba))
return -EIO;
status = beiscsi_process_mcc(phba);
......@@ -439,6 +442,7 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba)
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : FW Timed Out\n");
phba->fw_timeout = true;
beiscsi_ue_detect(phba);
return -EBUSY;
}
return 0;
......@@ -479,7 +483,8 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
u32 ready;
do {
if (phba->fw_timeout)
if (beiscsi_error(phba))
return -EIO;
ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
......@@ -491,6 +496,7 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : FW Timed Out\n");
phba->fw_timeout = true;
beiscsi_ue_detect(phba);
return -EBUSY;
}
......
......@@ -4717,6 +4717,8 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba)
phba->ctrl.mbox_mem_alloced.size,
phba->ctrl.mbox_mem_alloced.va,
phba->ctrl.mbox_mem_alloced.dma);
cancel_delayed_work_sync(&phba->beiscsi_hw_check_task);
}
static void beiscsi_remove(struct pci_dev *pcidev)
......@@ -4769,6 +4771,25 @@ static void beiscsi_msix_enable(struct beiscsi_hba *phba)
return;
}
/*
* beiscsi_hw_health_check()- Check adapter health
* @work: work item to check HW health
*
* Check if adapter in an unrecoverable state or not.
**/
static void
beiscsi_hw_health_check(struct work_struct *work)
{
struct beiscsi_hba *phba =
container_of(work, struct beiscsi_hba,
beiscsi_hw_check_task.work);
beiscsi_ue_detect(phba);
schedule_delayed_work(&phba->beiscsi_hw_check_task,
msecs_to_jiffies(1000));
}
static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
const struct pci_device_id *id)
{
......@@ -4892,6 +4913,8 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
goto free_twq;
}
INIT_DELAYED_WORK(&phba->beiscsi_hw_check_task,
beiscsi_hw_health_check);
phwi_ctrlr = phba->phwi_ctrlr;
phwi_context = phwi_ctrlr->phwi_ctxt;
......@@ -4941,6 +4964,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
"iSCSI boot info.\n");
beiscsi_create_def_ifaces(phba);
schedule_delayed_work(&phba->beiscsi_hw_check_task,
msecs_to_jiffies(1000));
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
"\n\n\n BM_%d : SUCCESS - DRIVER LOADED\n\n\n");
return 0;
......
......@@ -750,6 +750,11 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
void beiscsi_process_all_cqs(struct work_struct *work);
static inline bool beiscsi_error(struct beiscsi_hba *phba)
{
return phba->ue_detected || phba->fw_timeout;
}
struct pdu_nop_out {
u32 dw[12];
};
......
......@@ -22,6 +22,138 @@
#include <scsi/scsi_bsg_iscsi.h>
#include "be_mgmt.h"
#include "be_iscsi.h"
#include "be_main.h"
/* UE Status Low CSR */
static const char * const desc_ue_status_low[] = {
"CEV",
"CTX",
"DBUF",
"ERX",
"Host",
"MPU",
"NDMA",
"PTC ",
"RDMA ",
"RXF ",
"RXIPS ",
"RXULP0 ",
"RXULP1 ",
"RXULP2 ",
"TIM ",
"TPOST ",
"TPRE ",
"TXIPS ",
"TXULP0 ",
"TXULP1 ",
"UC ",
"WDMA ",
"TXULP2 ",
"HOST1 ",
"P0_OB_LINK ",
"P1_OB_LINK ",
"HOST_GPIO ",
"MBOX ",
"AXGMAC0",
"AXGMAC1",
"JTAG",
"MPU_INTPEND"
};
/* UE Status High CSR */
static const char * const desc_ue_status_hi[] = {
"LPCMEMHOST",
"MGMT_MAC",
"PCS0ONLINE",
"MPU_IRAM",
"PCS1ONLINE",
"PCTL0",
"PCTL1",
"PMEM",
"RR",
"TXPB",
"RXPP",
"XAUI",
"TXP",
"ARM",
"IPC",
"HOST2",
"HOST3",
"HOST4",
"HOST5",
"HOST6",
"HOST7",
"HOST8",
"HOST9",
"NETC",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown"
};
/*
* beiscsi_ue_detec()- Detect Unrecoverable Error on adapter
* @phba: Driver priv structure
*
* Read registers linked to UE and check for the UE status
**/
void beiscsi_ue_detect(struct beiscsi_hba *phba)
{
uint32_t ue_hi = 0, ue_lo = 0;
uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
uint8_t i = 0;
if (phba->ue_detected)
return;
pci_read_config_dword(phba->pcidev,
PCICFG_UE_STATUS_LOW, &ue_lo);
pci_read_config_dword(phba->pcidev,
PCICFG_UE_STATUS_MASK_LOW,
&ue_mask_lo);
pci_read_config_dword(phba->pcidev,
PCICFG_UE_STATUS_HIGH,
&ue_hi);
pci_read_config_dword(phba->pcidev,
PCICFG_UE_STATUS_MASK_HI,
&ue_mask_hi);
ue_lo = (ue_lo & ~ue_mask_lo);
ue_hi = (ue_hi & ~ue_mask_hi);
if (ue_lo || ue_hi) {
phba->ue_detected = true;
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BG_%d : Error detected on the adapter\n");
}
if (ue_lo) {
for (i = 0; ue_lo; ue_lo >>= 1, i++) {
if (ue_lo & 1)
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG,
"BG_%d : UE_LOW %s bit set\n",
desc_ue_status_low[i]);
}
}
if (ue_hi) {
for (i = 0; ue_hi; ue_hi >>= 1, i++) {
if (ue_hi & 1)
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG,
"BG_%d : UE_HIGH %s bit set\n",
desc_ue_status_hi[i]);
}
}
}
/**
* mgmt_reopen_session()- Reopen a session based on reopen_type
......
......@@ -30,6 +30,12 @@
#define IP_V6_LEN 16
#define IP_V4_LEN 4
/* UE Status and Mask register */
#define PCICFG_UE_STATUS_LOW 0xA0
#define PCICFG_UE_STATUS_HIGH 0xA4
#define PCICFG_UE_STATUS_MASK_LOW 0xA8
#define PCICFG_UE_STATUS_MASK_HI 0xAC
/**
* Pseudo amap definition in which each bit of the actual structure is defined
* 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,
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
struct wrb_handle *pwrb_handle);
void beiscsi_ue_detect(struct beiscsi_hba *phba);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment