[SCSI] be2iscsi: Adding crashdump support
These changes allow the driver to support crashdump. We need to reset the chip incase of a crashdump Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
5db3f33d68
commit
e9b9119350
|
@ -19,6 +19,86 @@
|
||||||
#include "be_mgmt.h"
|
#include "be_mgmt.h"
|
||||||
#include "be_main.h"
|
#include "be_main.h"
|
||||||
|
|
||||||
|
int beiscsi_pci_soft_reset(struct beiscsi_hba *phba)
|
||||||
|
{
|
||||||
|
u32 sreset;
|
||||||
|
u8 *pci_reset_offset = 0;
|
||||||
|
u8 *pci_online0_offset = 0;
|
||||||
|
u8 *pci_online1_offset = 0;
|
||||||
|
u32 pconline0 = 0;
|
||||||
|
u32 pconline1 = 0;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
pci_reset_offset = (u8 *)phba->pci_va + BE2_SOFT_RESET;
|
||||||
|
pci_online0_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE0;
|
||||||
|
pci_online1_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE1;
|
||||||
|
sreset = readl((void *)pci_reset_offset);
|
||||||
|
sreset |= BE2_SET_RESET;
|
||||||
|
writel(sreset, (void *)pci_reset_offset);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (sreset & BE2_SET_RESET) {
|
||||||
|
if (i > 64)
|
||||||
|
break;
|
||||||
|
msleep(100);
|
||||||
|
sreset = readl((void *)pci_reset_offset);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sreset & BE2_SET_RESET) {
|
||||||
|
printk(KERN_ERR "Soft Reset did not deassert\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
pconline1 = BE2_MPU_IRAM_ONLINE;
|
||||||
|
writel(pconline0, (void *)pci_online0_offset);
|
||||||
|
writel(pconline1, (void *)pci_online1_offset);
|
||||||
|
|
||||||
|
sreset = BE2_SET_RESET;
|
||||||
|
writel(sreset, (void *)pci_reset_offset);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (sreset & BE2_SET_RESET) {
|
||||||
|
if (i > 64)
|
||||||
|
break;
|
||||||
|
msleep(1);
|
||||||
|
sreset = readl((void *)pci_reset_offset);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (sreset & BE2_SET_RESET) {
|
||||||
|
printk(KERN_ERR "MPU Online Soft Reset did not deassert\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int be_chk_reset_complete(struct beiscsi_hba *phba)
|
||||||
|
{
|
||||||
|
unsigned int num_loop;
|
||||||
|
u8 *mpu_sem = 0;
|
||||||
|
u32 status;
|
||||||
|
|
||||||
|
num_loop = 1000;
|
||||||
|
mpu_sem = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
|
||||||
|
msleep(5000);
|
||||||
|
|
||||||
|
while (num_loop) {
|
||||||
|
status = readl((void *)mpu_sem);
|
||||||
|
|
||||||
|
if ((status & 0x80000000) || (status & 0x0000FFFF) == 0xC000)
|
||||||
|
break;
|
||||||
|
msleep(60);
|
||||||
|
num_loop--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status & 0x80000000) || (!num_loop)) {
|
||||||
|
printk(KERN_ERR "Failed in be_chk_reset_complete"
|
||||||
|
"status = 0x%x\n", status);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void be_mcc_notify(struct beiscsi_hba *phba)
|
void be_mcc_notify(struct beiscsi_hba *phba)
|
||||||
{
|
{
|
||||||
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
|
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
|
||||||
|
|
|
@ -901,6 +901,9 @@ struct be_fw_cfg {
|
||||||
* the cxn
|
* the cxn
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int beiscsi_pci_soft_reset(struct beiscsi_hba *phba);
|
||||||
|
int be_chk_reset_complete(struct beiscsi_hba *phba);
|
||||||
|
|
||||||
void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
|
void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
|
||||||
bool embedded, u8 sge_cnt);
|
bool embedded, u8 sge_cnt);
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
static unsigned int be_iopoll_budget = 10;
|
static unsigned int be_iopoll_budget = 10;
|
||||||
static unsigned int be_max_phys_size = 64;
|
static unsigned int be_max_phys_size = 64;
|
||||||
static unsigned int enable_msix = 1;
|
static unsigned int enable_msix = 1;
|
||||||
|
static unsigned int gcrashmode = 0;
|
||||||
|
static unsigned int num_hba = 0;
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
|
MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
|
||||||
MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
|
MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
|
||||||
|
@ -3731,6 +3733,8 @@ static void beiscsi_remove(struct pci_dev *pcidev)
|
||||||
struct hwi_context_memory *phwi_context;
|
struct hwi_context_memory *phwi_context;
|
||||||
struct be_eq_obj *pbe_eq;
|
struct be_eq_obj *pbe_eq;
|
||||||
unsigned int i, msix_vec;
|
unsigned int i, msix_vec;
|
||||||
|
u8 *real_offset = 0;
|
||||||
|
u32 value = 0;
|
||||||
|
|
||||||
phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
|
phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
|
||||||
if (!phba) {
|
if (!phba) {
|
||||||
|
@ -3759,6 +3763,14 @@ static void beiscsi_remove(struct pci_dev *pcidev)
|
||||||
|
|
||||||
beiscsi_clean_port(phba);
|
beiscsi_clean_port(phba);
|
||||||
beiscsi_free_mem(phba);
|
beiscsi_free_mem(phba);
|
||||||
|
real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
|
||||||
|
|
||||||
|
value = readl((void *)real_offset);
|
||||||
|
|
||||||
|
if (value & 0x00010000) {
|
||||||
|
value &= 0xfffeffff;
|
||||||
|
writel(value, (void *)real_offset);
|
||||||
|
}
|
||||||
beiscsi_unmap_pci_function(phba);
|
beiscsi_unmap_pci_function(phba);
|
||||||
pci_free_consistent(phba->pcidev,
|
pci_free_consistent(phba->pcidev,
|
||||||
phba->ctrl.mbox_mem_alloced.size,
|
phba->ctrl.mbox_mem_alloced.size,
|
||||||
|
@ -3792,6 +3804,8 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
|
||||||
struct hwi_context_memory *phwi_context;
|
struct hwi_context_memory *phwi_context;
|
||||||
struct be_eq_obj *pbe_eq;
|
struct be_eq_obj *pbe_eq;
|
||||||
int ret, num_cpus, i;
|
int ret, num_cpus, i;
|
||||||
|
u8 *real_offset = 0;
|
||||||
|
u32 value = 0;
|
||||||
|
|
||||||
ret = beiscsi_enable_pci(pcidev);
|
ret = beiscsi_enable_pci(pcidev);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -3837,6 +3851,33 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
|
||||||
goto hba_free;
|
goto hba_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!num_hba) {
|
||||||
|
real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
|
||||||
|
value = readl((void *)real_offset);
|
||||||
|
if (value & 0x00010000) {
|
||||||
|
gcrashmode++;
|
||||||
|
shost_printk(KERN_ERR, phba->shost,
|
||||||
|
"Loading Driver in crashdump mode\n");
|
||||||
|
ret = beiscsi_pci_soft_reset(phba);
|
||||||
|
if (ret) {
|
||||||
|
shost_printk(KERN_ERR, phba->shost,
|
||||||
|
"Reset Failed. Aborting Crashdump\n");
|
||||||
|
goto hba_free;
|
||||||
|
}
|
||||||
|
ret = be_chk_reset_complete(phba);
|
||||||
|
if (ret) {
|
||||||
|
shost_printk(KERN_ERR, phba->shost,
|
||||||
|
"Failed to get out of reset."
|
||||||
|
"Aborting Crashdump\n");
|
||||||
|
goto hba_free;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value |= 0x00010000;
|
||||||
|
writel(value, (void *)real_offset);
|
||||||
|
num_hba++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_init(&phba->io_sgl_lock);
|
spin_lock_init(&phba->io_sgl_lock);
|
||||||
spin_lock_init(&phba->mgmt_sgl_lock);
|
spin_lock_init(&phba->mgmt_sgl_lock);
|
||||||
spin_lock_init(&phba->isr_lock);
|
spin_lock_init(&phba->isr_lock);
|
||||||
|
@ -3907,6 +3948,15 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
|
||||||
beiscsi_clean_port(phba);
|
beiscsi_clean_port(phba);
|
||||||
beiscsi_free_mem(phba);
|
beiscsi_free_mem(phba);
|
||||||
free_port:
|
free_port:
|
||||||
|
real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
|
||||||
|
|
||||||
|
value = readl((void *)real_offset);
|
||||||
|
|
||||||
|
if (value & 0x00010000) {
|
||||||
|
value &= 0xfffeffff;
|
||||||
|
writel(value, (void *)real_offset);
|
||||||
|
}
|
||||||
|
|
||||||
pci_free_consistent(phba->pcidev,
|
pci_free_consistent(phba->pcidev,
|
||||||
phba->ctrl.mbox_mem_alloced.size,
|
phba->ctrl.mbox_mem_alloced.size,
|
||||||
phba->ctrl.mbox_mem_alloced.va,
|
phba->ctrl.mbox_mem_alloced.va,
|
||||||
|
|
|
@ -69,7 +69,14 @@
|
||||||
#define BEISCSI_NUM_DEVICES_SUPPORTED 0x01
|
#define BEISCSI_NUM_DEVICES_SUPPORTED 0x01
|
||||||
#define BEISCSI_MAX_FRAGS_INIT 192
|
#define BEISCSI_MAX_FRAGS_INIT 192
|
||||||
#define BE_NUM_MSIX_ENTRIES 1
|
#define BE_NUM_MSIX_ENTRIES 1
|
||||||
#define MPU_EP_SEMAPHORE 0xac
|
|
||||||
|
#define MPU_EP_CONTROL 0
|
||||||
|
#define MPU_EP_SEMAPHORE 0xac
|
||||||
|
#define BE2_SOFT_RESET 0x5c
|
||||||
|
#define BE2_PCI_ONLINE0 0xb0
|
||||||
|
#define BE2_PCI_ONLINE1 0xb4
|
||||||
|
#define BE2_SET_RESET 0x80
|
||||||
|
#define BE2_MPU_IRAM_ONLINE 0x00000080
|
||||||
|
|
||||||
#define BE_SENSE_INFO_SIZE 258
|
#define BE_SENSE_INFO_SIZE 258
|
||||||
#define BE_ISCSI_PDU_HEADER_SIZE 64
|
#define BE_ISCSI_PDU_HEADER_SIZE 64
|
||||||
|
|
Loading…
Reference in New Issue