diff options
-rw-r--r-- | drivers/scsi/be2iscsi/be.h | 9 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 7 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 90 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 7 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 11 |
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 | ||
112 | struct beiscsi_mcc_tag_state { | 112 | struct 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 | ||
744 | void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag); | 744 | void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag); |
745 | 745 | ||
746 | int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *, | 746 | int beiscsi_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *, |
747 | int num); | 747 | int num); |
748 | int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba, | 748 | int 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 | ||
5342 | static void be_eqd_update(struct beiscsi_hba *phba) | 5343 | static 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 | |||
5356 | static 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 | **/ | ||
5402 | static void | ||
5403 | beiscsi_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; |
5564 | ret_err: | 5564 | ret_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 | ||
155 | int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, | 155 | int 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; |