summaryrefslogtreecommitdiff
path: root/drivers/scsi/be2iscsi/be_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/be2iscsi/be_main.c')
-rw-r--r--drivers/scsi/be2iscsi/be_main.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 915c26b23ab6..30d74a06b993 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2005 - 2013 Emulex
+ * Copyright (C) 2005 - 2014 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -2068,7 +2068,7 @@ static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba)
* return
* Number of Completion Entries processed.
**/
-static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
+unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
{
struct be_queue_info *cq;
struct sol_cqe *sol;
@@ -2110,6 +2110,18 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
cri_index = BE_GET_CRI_FROM_CID(cid);
ep = phba->ep_array[cri_index];
+
+ if (ep == NULL) {
+ /* connection has already been freed
+ * just move on to next one
+ */
+ beiscsi_log(phba, KERN_WARNING,
+ BEISCSI_LOG_INIT,
+ "BM_%d : proc cqe of disconn ep: cid %d\n",
+ cid);
+ goto proc_next_cqe;
+ }
+
beiscsi_ep = ep->dd_data;
beiscsi_conn = beiscsi_ep->conn;
@@ -2219,6 +2231,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
break;
}
+proc_next_cqe:
AMAP_SET_BITS(struct amap_sol_cqe, valid, sol, 0);
queue_tail_inc(cq);
sol = queue_tail_node(cq);
@@ -4377,6 +4390,10 @@ static int beiscsi_setup_boot_info(struct beiscsi_hba *phba)
{
struct iscsi_boot_kobj *boot_kobj;
+ /* it has been created previously */
+ if (phba->boot_kset)
+ return 0;
+
/* get boot info using mgmt cmd */
if (beiscsi_get_boot_info(phba))
/* Try to see if we can carry on without this */
@@ -5206,6 +5223,7 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba,
free_irq(phba->pcidev->irq, phba);
}
pci_disable_msix(phba->pcidev);
+ cancel_delayed_work_sync(&phba->beiscsi_hw_check_task);
for (i = 0; i < phba->num_cpus; i++) {
pbe_eq = &phwi_context->be_eq[i];
@@ -5227,7 +5245,6 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba,
hwi_cleanup(phba);
}
- cancel_delayed_work_sync(&phba->beiscsi_hw_check_task);
}
static void beiscsi_remove(struct pci_dev *pcidev)
@@ -5276,9 +5293,9 @@ static void beiscsi_msix_enable(struct beiscsi_hba *phba)
for (i = 0; i <= phba->num_cpus; i++)
phba->msix_entries[i].entry = i;
- status = pci_enable_msix(phba->pcidev, phba->msix_entries,
- (phba->num_cpus + 1));
- if (!status)
+ status = pci_enable_msix_range(phba->pcidev, phba->msix_entries,
+ phba->num_cpus + 1, phba->num_cpus + 1);
+ if (status > 0)
phba->msix_enabled = true;
return;
@@ -5335,6 +5352,14 @@ static void be_eqd_update(struct beiscsi_hba *phba)
}
}
+static void be_check_boot_session(struct beiscsi_hba *phba)
+{
+ if (beiscsi_setup_boot_info(phba))
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Could not set up "
+ "iSCSI boot info on async event.\n");
+}
+
/*
* beiscsi_hw_health_check()- Check adapter health
* @work: work item to check HW health
@@ -5350,6 +5375,11 @@ beiscsi_hw_health_check(struct work_struct *work)
be_eqd_update(phba);
+ if (phba->state & BE_ADAPTER_CHECK_BOOT) {
+ phba->state &= ~BE_ADAPTER_CHECK_BOOT;
+ be_check_boot_session(phba);
+ }
+
beiscsi_ue_detect(phba);
schedule_delayed_work(&phba->beiscsi_hw_check_task,