aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/be2iscsi/be.h9
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c7
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h2
-rw-r--r--drivers/scsi/be2iscsi/be_main.c90
-rw-r--r--drivers/scsi/be2iscsi/be_main.h7
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c11
6 files changed, 75 insertions, 51 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 454002d98bcd..bb4042c9acfb 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -89,7 +89,7 @@ struct be_aic_obj { /* Adaptive interrupt coalescing (AIC) info */
89 u32 max_eqd; /* in usecs */ 89 u32 max_eqd; /* in usecs */
90 u32 prev_eqd; /* in usecs */ 90 u32 prev_eqd; /* in usecs */
91 u32 et_eqd; /* configured val when aic is off */ 91 u32 et_eqd; /* configured val when aic is off */
92 ulong jiffs; 92 ulong jiffies;
93 u64 eq_prev; /* Used to calculate eqe */ 93 u64 eq_prev; /* Used to calculate eqe */
94}; 94};
95 95
@@ -111,9 +111,10 @@ struct be_mcc_obj {
111 111
112struct beiscsi_mcc_tag_state { 112struct beiscsi_mcc_tag_state {
113 unsigned long tag_state; 113 unsigned long tag_state;
114#define MCC_TAG_STATE_RUNNING 1 114#define MCC_TAG_STATE_RUNNING 0
115#define MCC_TAG_STATE_TIMEOUT 2 115#define MCC_TAG_STATE_TIMEOUT 1
116#define MCC_TAG_STATE_ASYNC 3 116#define MCC_TAG_STATE_ASYNC 2
117#define MCC_TAG_STATE_IGNORE 3
117 void (*cbfn)(struct beiscsi_hba *, unsigned int); 118 void (*cbfn)(struct beiscsi_hba *, unsigned int);
118 struct be_dma_mem tag_mem_state; 119 struct be_dma_mem tag_mem_state;
119}; 120};
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 27d10cee0c40..7cb009e0030e 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -515,6 +515,13 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
515 return 0; 515 return 0;
516 } 516 }
517 517
518 if (test_bit(MCC_TAG_STATE_IGNORE, &ctrl->ptag_state[tag].tag_state)) {
519 /* just check completion status and free wrb */
520 __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
521 free_mcc_wrb(ctrl, tag);
522 return 0;
523 }
524
518 wake_up_interruptible(&ctrl->mcc_wait[tag]); 525 wake_up_interruptible(&ctrl->mcc_wait[tag]);
519 return 0; 526 return 0;
520} 527}
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 0510b6767341..6fb9673248b3 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -743,7 +743,7 @@ unsigned int be_cmd_get_initname(struct beiscsi_hba *phba);
743 743
744void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag); 744void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag);
745 745
746int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *, 746int beiscsi_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *,
747 int num); 747 int num);
748int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba, 748int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
749 unsigned int tag, 749 unsigned int tag,
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index eb4ce17a683d..3dd4f9d126ae 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -4999,8 +4999,9 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba)
4999 if (phba->pcidev->irq) 4999 if (phba->pcidev->irq)
5000 free_irq(phba->pcidev->irq, phba); 5000 free_irq(phba->pcidev->irq, phba);
5001 pci_disable_msix(phba->pcidev); 5001 pci_disable_msix(phba->pcidev);
5002 cancel_delayed_work_sync(&phba->beiscsi_hw_check_task); 5002 cancel_delayed_work_sync(&phba->eqd_update);
5003 cancel_work_sync(&phba->boot_work); 5003 cancel_work_sync(&phba->boot_work);
5004 del_timer_sync(&phba->hw_check);
5004 5005
5005 for (i = 0; i < phba->num_cpus; i++) { 5006 for (i = 0; i < phba->num_cpus; i++) {
5006 pbe_eq = &phwi_context->be_eq[i]; 5007 pbe_eq = &phwi_context->be_eq[i];
@@ -5339,18 +5340,32 @@ static void beiscsi_boot_work(struct work_struct *work)
5339 } 5340 }
5340} 5341}
5341 5342
5342static void be_eqd_update(struct beiscsi_hba *phba) 5343static void beiscsi_hw_health_check(unsigned long ptr)
5343{ 5344{
5345 struct beiscsi_hba *phba;
5346
5347 phba = (struct beiscsi_hba *)ptr;
5348 beiscsi_ue_detect(phba);
5349 if (test_bit(BEISCSI_HBA_IN_UE, &phba->state))
5350 return;
5351
5352 mod_timer(&phba->hw_check,
5353 jiffies + msecs_to_jiffies(BEISCSI_UE_DETECT_INTERVAL));
5354}
5355
5356static void beiscsi_eqd_update_work(struct work_struct *work)
5357{
5358 struct hwi_context_memory *phwi_context;
5344 struct be_set_eqd set_eqd[MAX_CPUS]; 5359 struct be_set_eqd set_eqd[MAX_CPUS];
5345 struct be_aic_obj *aic;
5346 struct be_eq_obj *pbe_eq;
5347 struct hwi_controller *phwi_ctrlr; 5360 struct hwi_controller *phwi_ctrlr;
5348 struct hwi_context_memory *phwi_context; 5361 struct be_eq_obj *pbe_eq;
5362 struct beiscsi_hba *phba;
5363 unsigned int pps, delta;
5364 struct be_aic_obj *aic;
5349 int eqd, i, num = 0; 5365 int eqd, i, num = 0;
5350 ulong now; 5366 unsigned long now;
5351 u32 pps, delta;
5352 unsigned int tag;
5353 5367
5368 phba = container_of(work, struct beiscsi_hba, eqd_update.work);
5354 if (beiscsi_hba_in_error(phba)) 5369 if (beiscsi_hba_in_error(phba))
5355 return; 5370 return;
5356 5371
@@ -5361,13 +5376,13 @@ static void be_eqd_update(struct beiscsi_hba *phba)
5361 aic = &phba->aic_obj[i]; 5376 aic = &phba->aic_obj[i];
5362 pbe_eq = &phwi_context->be_eq[i]; 5377 pbe_eq = &phwi_context->be_eq[i];
5363 now = jiffies; 5378 now = jiffies;
5364 if (!aic->jiffs || time_before(now, aic->jiffs) || 5379 if (!aic->jiffies || time_before(now, aic->jiffies) ||
5365 pbe_eq->cq_count < aic->eq_prev) { 5380 pbe_eq->cq_count < aic->eq_prev) {
5366 aic->jiffs = now; 5381 aic->jiffies = now;
5367 aic->eq_prev = pbe_eq->cq_count; 5382 aic->eq_prev = pbe_eq->cq_count;
5368 continue; 5383 continue;
5369 } 5384 }
5370 delta = jiffies_to_msecs(now - aic->jiffs); 5385 delta = jiffies_to_msecs(now - aic->jiffies);
5371 pps = (((u32)(pbe_eq->cq_count - aic->eq_prev) * 1000) / delta); 5386 pps = (((u32)(pbe_eq->cq_count - aic->eq_prev) * 1000) / delta);
5372 eqd = (pps / 1500) << 2; 5387 eqd = (pps / 1500) << 2;
5373 5388
@@ -5376,7 +5391,7 @@ static void be_eqd_update(struct beiscsi_hba *phba)
5376 eqd = min_t(u32, eqd, phwi_context->max_eqd); 5391 eqd = min_t(u32, eqd, phwi_context->max_eqd);
5377 eqd = max_t(u32, eqd, phwi_context->min_eqd); 5392 eqd = max_t(u32, eqd, phwi_context->min_eqd);
5378 5393
5379 aic->jiffs = now; 5394 aic->jiffies = now;
5380 aic->eq_prev = pbe_eq->cq_count; 5395 aic->eq_prev = pbe_eq->cq_count;
5381 5396
5382 if (eqd != aic->prev_eqd) { 5397 if (eqd != aic->prev_eqd) {
@@ -5386,32 +5401,12 @@ static void be_eqd_update(struct beiscsi_hba *phba)
5386 num++; 5401 num++;
5387 } 5402 }
5388 } 5403 }
5389 if (num) { 5404 if (num)
5390 tag = be_cmd_modify_eq_delay(phba, set_eqd, num); 5405 /* completion of this is ignored */
5391 if (tag) 5406 beiscsi_modify_eq_delay(phba, set_eqd, num);
5392 beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
5393 }
5394}
5395 5407
5396/* 5408 schedule_delayed_work(&phba->eqd_update,
5397 * beiscsi_hw_health_check()- Check adapter health 5409 msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL));
5398 * @work: work item to check HW health
5399 *
5400 * Check if adapter in an unrecoverable state or not.
5401 **/
5402static void
5403beiscsi_hw_health_check(struct work_struct *work)
5404{
5405 struct beiscsi_hba *phba =
5406 container_of(work, struct beiscsi_hba,
5407 beiscsi_hw_check_task.work);
5408
5409 be_eqd_update(phba);
5410
5411 beiscsi_ue_detect(phba);
5412
5413 schedule_delayed_work(&phba->beiscsi_hw_check_task,
5414 msecs_to_jiffies(1000));
5415} 5410}
5416 5411
5417 5412
@@ -5560,6 +5555,11 @@ static void beiscsi_eeh_resume(struct pci_dev *pdev)
5560 hwi_enable_intr(phba); 5555 hwi_enable_intr(phba);
5561 clear_bit(BEISCSI_HBA_PCI_ERR, &phba->state); 5556 clear_bit(BEISCSI_HBA_PCI_ERR, &phba->state);
5562 5557
5558 /* start hw_check timer and eqd_update work */
5559 schedule_delayed_work(&phba->eqd_update,
5560 msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL));
5561 mod_timer(&phba->hw_check,
5562 jiffies + msecs_to_jiffies(BEISCSI_UE_DETECT_INTERVAL));
5563 return; 5563 return;
5564ret_err: 5564ret_err:
5565 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 5565 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -5707,8 +5707,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5707 goto free_twq; 5707 goto free_twq;
5708 } 5708 }
5709 5709
5710 INIT_DELAYED_WORK(&phba->beiscsi_hw_check_task, 5710 INIT_DELAYED_WORK(&phba->eqd_update, beiscsi_eqd_update_work);
5711 beiscsi_hw_health_check);
5712 5711
5713 phwi_ctrlr = phba->phwi_ctrlr; 5712 phwi_ctrlr = phba->phwi_ctrlr;
5714 phwi_context = phwi_ctrlr->phwi_ctxt; 5713 phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -5749,8 +5748,17 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5749 } 5748 }
5750 5749
5751 beiscsi_iface_create_default(phba); 5750 beiscsi_iface_create_default(phba);
5752 schedule_delayed_work(&phba->beiscsi_hw_check_task, 5751 schedule_delayed_work(&phba->eqd_update,
5753 msecs_to_jiffies(1000)); 5752 msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL));
5753 /**
5754 * Start UE detection here. UE before this will cause stall in probe
5755 * and eventually fail the probe.
5756 */
5757 init_timer(&phba->hw_check);
5758 phba->hw_check.function = beiscsi_hw_health_check;
5759 phba->hw_check.data = (unsigned long)phba;
5760 mod_timer(&phba->hw_check,
5761 jiffies + msecs_to_jiffies(BEISCSI_UE_DETECT_INTERVAL));
5754 5762
5755 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, 5763 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
5756 "\n\n\n BM_%d : SUCCESS - DRIVER LOADED\n\n\n"); 5764 "\n\n\n BM_%d : SUCCESS - DRIVER LOADED\n\n\n");
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 780c3fc16ec6..0d34ac611d2f 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -414,7 +414,12 @@ struct beiscsi_hba {
414 (1 << BEISCSI_HBA_IN_UE)) 414 (1 << BEISCSI_HBA_IN_UE))
415 415
416 u8 optic_state; 416 u8 optic_state;
417 struct delayed_work beiscsi_hw_check_task; 417 struct delayed_work eqd_update;
418 /* update EQ delay timer every 1000ms */
419#define BEISCSI_EQD_UPDATE_INTERVAL 1000
420 struct timer_list hw_check;
421 /* check for UE every 1000ms */
422#define BEISCSI_UE_DETECT_INTERVAL 1000
418 423
419 bool mac_addr_set; 424 bool mac_addr_set;
420 u8 mac_address[ETH_ALEN]; 425 u8 mac_address[ETH_ALEN];
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 756e7ae33e2c..60a116388467 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -97,7 +97,7 @@ static const char * const desc_ue_status_hi[] = {
97}; 97};
98 98
99/* 99/*
100 * beiscsi_ue_detec()- Detect Unrecoverable Error on adapter 100 * beiscsi_ue_detect()- Detect Unrecoverable Error on adapter
101 * @phba: Driver priv structure 101 * @phba: Driver priv structure
102 * 102 *
103 * Read registers linked to UE and check for the UE status 103 * Read registers linked to UE and check for the UE status
@@ -152,8 +152,9 @@ void beiscsi_ue_detect(struct beiscsi_hba *phba)
152 } 152 }
153} 153}
154 154
155int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, 155int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
156 struct be_set_eqd *set_eqd, int num) 156 struct be_set_eqd *set_eqd,
157 int num)
157{ 158{
158 struct be_ctrl_info *ctrl = &phba->ctrl; 159 struct be_ctrl_info *ctrl = &phba->ctrl;
159 struct be_mcc_wrb *wrb; 160 struct be_mcc_wrb *wrb;
@@ -171,7 +172,7 @@ int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
171 req = embedded_payload(wrb); 172 req = embedded_payload(wrb);
172 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 173 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
173 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 174 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
174 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req)); 175 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
175 176
176 req->num_eq = cpu_to_le32(num); 177 req->num_eq = cpu_to_le32(num);
177 for (i = 0; i < num; i++) { 178 for (i = 0; i < num; i++) {
@@ -181,6 +182,8 @@ int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
181 cpu_to_le32(set_eqd[i].delay_multiplier); 182 cpu_to_le32(set_eqd[i].delay_multiplier);
182 } 183 }
183 184
185 /* ignore the completion of this mbox command */
186 set_bit(MCC_TAG_STATE_IGNORE, &ctrl->ptag_state[tag].tag_state);
184 be_mcc_notify(phba, tag); 187 be_mcc_notify(phba, tag);
185 mutex_unlock(&ctrl->mbox_lock); 188 mutex_unlock(&ctrl->mbox_lock);
186 return tag; 189 return tag;