mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-16 10:17:32 +00:00
[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: John Soni Jose <sony.john-n@emulex.com> Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
e175defea7
commit
7a15800357
@ -157,6 +157,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
|
|||||||
struct be_cmd_req_hdr *ioctl_hdr;
|
struct be_cmd_req_hdr *ioctl_hdr;
|
||||||
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
|
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
|
||||||
|
|
||||||
|
if (beiscsi_error(phba))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
/* wait for the mccq completion */
|
/* wait for the mccq completion */
|
||||||
rc = wait_event_interruptible_timeout(
|
rc = wait_event_interruptible_timeout(
|
||||||
phba->ctrl.mcc_wait[tag],
|
phba->ctrl.mcc_wait[tag],
|
||||||
@ -423,7 +426,7 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba)
|
|||||||
{
|
{
|
||||||
int i, status;
|
int i, status;
|
||||||
for (i = 0; i < mcc_timeout; i++) {
|
for (i = 0; i < mcc_timeout; i++) {
|
||||||
if (phba->fw_timeout)
|
if (beiscsi_error(phba))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
status = beiscsi_process_mcc(phba);
|
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,
|
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
|
||||||
"BC_%d : FW Timed Out\n");
|
"BC_%d : FW Timed Out\n");
|
||||||
phba->fw_timeout = true;
|
phba->fw_timeout = true;
|
||||||
|
beiscsi_ue_detect(phba);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -479,7 +483,8 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
|
|||||||
u32 ready;
|
u32 ready;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (phba->fw_timeout)
|
|
||||||
|
if (beiscsi_error(phba))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
|
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,
|
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
|
||||||
"BC_%d : FW Timed Out\n");
|
"BC_%d : FW Timed Out\n");
|
||||||
phba->fw_timeout = true;
|
phba->fw_timeout = true;
|
||||||
|
beiscsi_ue_detect(phba);
|
||||||
return -EBUSY;
|
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.size,
|
||||||
phba->ctrl.mbox_mem_alloced.va,
|
phba->ctrl.mbox_mem_alloced.va,
|
||||||
phba->ctrl.mbox_mem_alloced.dma);
|
phba->ctrl.mbox_mem_alloced.dma);
|
||||||
|
|
||||||
|
cancel_delayed_work_sync(&phba->beiscsi_hw_check_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void beiscsi_remove(struct pci_dev *pcidev)
|
static void beiscsi_remove(struct pci_dev *pcidev)
|
||||||
@ -4769,6 +4771,25 @@ static void beiscsi_msix_enable(struct beiscsi_hba *phba)
|
|||||||
return;
|
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,
|
static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
|
||||||
const struct pci_device_id *id)
|
const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
@ -4892,6 +4913,8 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
|
|||||||
goto free_twq;
|
goto free_twq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INIT_DELAYED_WORK(&phba->beiscsi_hw_check_task,
|
||||||
|
beiscsi_hw_health_check);
|
||||||
|
|
||||||
phwi_ctrlr = phba->phwi_ctrlr;
|
phwi_ctrlr = phba->phwi_ctrlr;
|
||||||
phwi_context = phwi_ctrlr->phwi_ctxt;
|
phwi_context = phwi_ctrlr->phwi_ctxt;
|
||||||
@ -4941,6 +4964,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
|
|||||||
"iSCSI boot info.\n");
|
"iSCSI boot info.\n");
|
||||||
|
|
||||||
beiscsi_create_def_ifaces(phba);
|
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,
|
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
|
||||||
"\n\n\n BM_%d : SUCCESS - DRIVER LOADED\n\n\n");
|
"\n\n\n BM_%d : SUCCESS - DRIVER LOADED\n\n\n");
|
||||||
return 0;
|
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);
|
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 {
|
struct pdu_nop_out {
|
||||||
u32 dw[12];
|
u32 dw[12];
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,138 @@
|
|||||||
#include <scsi/scsi_bsg_iscsi.h>
|
#include <scsi/scsi_bsg_iscsi.h>
|
||||||
#include "be_mgmt.h"
|
#include "be_mgmt.h"
|
||||||
#include "be_iscsi.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
|
* mgmt_reopen_session()- Reopen a session based on reopen_type
|
||||||
|
@ -30,6 +30,12 @@
|
|||||||
#define IP_V6_LEN 16
|
#define IP_V6_LEN 16
|
||||||
#define IP_V4_LEN 4
|
#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
|
* 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
|
* 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,
|
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
|
||||||
struct wrb_handle *pwrb_handle);
|
struct wrb_handle *pwrb_handle);
|
||||||
|
void beiscsi_ue_detect(struct beiscsi_hba *phba);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user