aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuinn Tran <quinn.tran@cavium.com>2018-08-02 16:16:52 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2018-08-02 16:56:18 -0400
commitb2000805a9759d315f56eecaca7779aa9197a72f (patch)
tree8196cb8cd909b640c18b72b4ef55a4732dbb5d1c
parentcb97f2c2e8d9f8c71ddbf04ad57e163ee6d86474 (diff)
scsi: qla2xxx: Flush mailbox commands on chip reset
Flush pending mailbox commands on chip reset. Wake up command that's waiting for an interrupt and wait for mailbox counters to go to zero. Signed-off-by: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h5
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c21
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c50
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c3
4 files changed, 74 insertions, 5 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index ee4d1f4fdf95..40bcf938cf4f 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3598,6 +3598,7 @@ struct qla_hw_data {
3598 uint32_t detected_lr_sfp:1; 3598 uint32_t detected_lr_sfp:1;
3599 uint32_t using_lr_setting:1; 3599 uint32_t using_lr_setting:1;
3600 uint32_t rida_fmt2:1; 3600 uint32_t rida_fmt2:1;
3601 uint32_t purge_mbox:1;
3601 } flags; 3602 } flags;
3602 3603
3603 uint16_t max_exchg; 3604 uint16_t max_exchg;
@@ -3843,6 +3844,9 @@ struct qla_hw_data {
3843 int port_down_retry_count; 3844 int port_down_retry_count;
3844 uint8_t mbx_count; 3845 uint8_t mbx_count;
3845 uint8_t aen_mbx_count; 3846 uint8_t aen_mbx_count;
3847 atomic_t num_pend_mbx_stage1;
3848 atomic_t num_pend_mbx_stage2;
3849 atomic_t num_pend_mbx_stage3;
3846 3850
3847 uint32_t login_retry_count; 3851 uint32_t login_retry_count;
3848 /* SNS command interfaces. */ 3852 /* SNS command interfaces. */
@@ -4156,6 +4160,7 @@ struct qla_hw_data {
4156 struct work_struct board_disable; 4160 struct work_struct board_disable;
4157 4161
4158 struct mr_data_fx00 mr; 4162 struct mr_data_fx00 mr;
4163 uint32_t chip_reset;
4159 4164
4160 struct qlt_hw_data tgt; 4165 struct qlt_hw_data tgt;
4161 int allow_cna_fw_dump; 4166 int allow_cna_fw_dump;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index bb565f556c2f..a10a8bb895e9 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -6283,6 +6283,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
6283 ql_log(ql_log_info, vha, 0x00af, 6283 ql_log(ql_log_info, vha, 0x00af,
6284 "Performing ISP error recovery - ha=%p.\n", ha); 6284 "Performing ISP error recovery - ha=%p.\n", ha);
6285 6285
6286 ha->flags.purge_mbox = 1;
6286 /* For ISP82XX, reset_chip is just disabling interrupts. 6287 /* For ISP82XX, reset_chip is just disabling interrupts.
6287 * Driver waits for the completion of the commands. 6288 * Driver waits for the completion of the commands.
6288 * the interrupts need to be enabled. 6289 * the interrupts need to be enabled.
@@ -6297,13 +6298,31 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
6297 ha->current_topology = 0; 6298 ha->current_topology = 0;
6298 ha->flags.fw_started = 0; 6299 ha->flags.fw_started = 0;
6299 ha->flags.fw_init_done = 0; 6300 ha->flags.fw_init_done = 0;
6300 ha->base_qpair->chip_reset++; 6301 ha->chip_reset++;
6302 ha->base_qpair->chip_reset = ha->chip_reset;
6301 for (i = 0; i < ha->max_qpairs; i++) { 6303 for (i = 0; i < ha->max_qpairs; i++) {
6302 if (ha->queue_pair_map[i]) 6304 if (ha->queue_pair_map[i])
6303 ha->queue_pair_map[i]->chip_reset = 6305 ha->queue_pair_map[i]->chip_reset =
6304 ha->base_qpair->chip_reset; 6306 ha->base_qpair->chip_reset;
6305 } 6307 }
6306 6308
6309 /* purge MBox commands */
6310 if (atomic_read(&ha->num_pend_mbx_stage3)) {
6311 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
6312 complete(&ha->mbx_intr_comp);
6313 }
6314
6315 i = 0;
6316 while (atomic_read(&ha->num_pend_mbx_stage3) ||
6317 atomic_read(&ha->num_pend_mbx_stage2) ||
6318 atomic_read(&ha->num_pend_mbx_stage1)) {
6319 msleep(20);
6320 i++;
6321 if (i > 50)
6322 break;
6323 }
6324 ha->flags.purge_mbox = 0;
6325
6307 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); 6326 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
6308 if (atomic_read(&vha->loop_state) != LOOP_DOWN) { 6327 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
6309 atomic_set(&vha->loop_state, LOOP_DOWN); 6328 atomic_set(&vha->loop_state, LOOP_DOWN);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 17537f0b3b54..10847cdca093 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -110,6 +110,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
110 unsigned long wait_time; 110 unsigned long wait_time;
111 struct qla_hw_data *ha = vha->hw; 111 struct qla_hw_data *ha = vha->hw;
112 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 112 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
113 u32 chip_reset;
113 114
114 115
115 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__); 116 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
@@ -140,7 +141,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
140 141
141 rval = QLA_SUCCESS; 142 rval = QLA_SUCCESS;
142 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); 143 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
143 144 chip_reset = ha->chip_reset;
144 145
145 if (ha->flags.pci_channel_io_perm_failure) { 146 if (ha->flags.pci_channel_io_perm_failure) {
146 ql_log(ql_log_warn, vha, 0x1003, 147 ql_log(ql_log_warn, vha, 0x1003,
@@ -167,6 +168,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
167 return QLA_FUNCTION_TIMEOUT; 168 return QLA_FUNCTION_TIMEOUT;
168 } 169 }
169 170
171 atomic_inc(&ha->num_pend_mbx_stage1);
170 /* 172 /*
171 * Wait for active mailbox commands to finish by waiting at most tov 173 * Wait for active mailbox commands to finish by waiting at most tov
172 * seconds. This is to serialize actual issuing of mailbox cmds during 174 * seconds. This is to serialize actual issuing of mailbox cmds during
@@ -177,8 +179,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
177 ql_log(ql_log_warn, vha, 0xd035, 179 ql_log(ql_log_warn, vha, 0xd035,
178 "Cmd access timeout, cmd=0x%x, Exiting.\n", 180 "Cmd access timeout, cmd=0x%x, Exiting.\n",
179 mcp->mb[0]); 181 mcp->mb[0]);
182 atomic_dec(&ha->num_pend_mbx_stage1);
180 return QLA_FUNCTION_TIMEOUT; 183 return QLA_FUNCTION_TIMEOUT;
181 } 184 }
185 atomic_dec(&ha->num_pend_mbx_stage1);
186 if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) {
187 rval = QLA_ABORTED;
188 goto premature_exit;
189 }
182 190
183 ha->flags.mbox_busy = 1; 191 ha->flags.mbox_busy = 1;
184 /* Save mailbox command for debug */ 192 /* Save mailbox command for debug */
@@ -189,6 +197,13 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
189 197
190 spin_lock_irqsave(&ha->hardware_lock, flags); 198 spin_lock_irqsave(&ha->hardware_lock, flags);
191 199
200 if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) {
201 rval = QLA_ABORTED;
202 ha->flags.mbox_busy = 0;
203 spin_unlock_irqrestore(&ha->hardware_lock, flags);
204 goto premature_exit;
205 }
206
192 /* Load mailbox registers. */ 207 /* Load mailbox registers. */
193 if (IS_P3P_TYPE(ha)) 208 if (IS_P3P_TYPE(ha))
194 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0]; 209 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
@@ -231,7 +246,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
231 "jiffies=%lx.\n", jiffies); 246 "jiffies=%lx.\n", jiffies);
232 247
233 /* Wait for mbx cmd completion until timeout */ 248 /* Wait for mbx cmd completion until timeout */
234 249 atomic_inc(&ha->num_pend_mbx_stage2);
235 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) { 250 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
236 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); 251 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
237 252
@@ -241,6 +256,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
241 spin_unlock_irqrestore(&ha->hardware_lock, 256 spin_unlock_irqrestore(&ha->hardware_lock,
242 flags); 257 flags);
243 ha->flags.mbox_busy = 0; 258 ha->flags.mbox_busy = 0;
259 atomic_dec(&ha->num_pend_mbx_stage2);
244 ql_dbg(ql_dbg_mbx, vha, 0x1010, 260 ql_dbg(ql_dbg_mbx, vha, 0x1010,
245 "Pending mailbox timeout, exiting.\n"); 261 "Pending mailbox timeout, exiting.\n");
246 rval = QLA_FUNCTION_TIMEOUT; 262 rval = QLA_FUNCTION_TIMEOUT;
@@ -254,6 +270,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
254 spin_unlock_irqrestore(&ha->hardware_lock, flags); 270 spin_unlock_irqrestore(&ha->hardware_lock, flags);
255 271
256 wait_time = jiffies; 272 wait_time = jiffies;
273 atomic_inc(&ha->num_pend_mbx_stage3);
257 if (!wait_for_completion_timeout(&ha->mbx_intr_comp, 274 if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
258 mcp->tov * HZ)) { 275 mcp->tov * HZ)) {
259 ql_dbg(ql_dbg_mbx, vha, 0x117a, 276 ql_dbg(ql_dbg_mbx, vha, 0x117a,
@@ -261,7 +278,17 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
261 spin_lock_irqsave(&ha->hardware_lock, flags); 278 spin_lock_irqsave(&ha->hardware_lock, flags);
262 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); 279 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
263 spin_unlock_irqrestore(&ha->hardware_lock, flags); 280 spin_unlock_irqrestore(&ha->hardware_lock, flags);
281
282 } else if (ha->flags.purge_mbox ||
283 chip_reset != ha->chip_reset) {
284 ha->flags.mbox_busy = 0;
285 atomic_dec(&ha->num_pend_mbx_stage2);
286 atomic_dec(&ha->num_pend_mbx_stage3);
287 rval = QLA_ABORTED;
288 goto premature_exit;
264 } 289 }
290 atomic_dec(&ha->num_pend_mbx_stage3);
291
265 if (time_after(jiffies, wait_time + 5 * HZ)) 292 if (time_after(jiffies, wait_time + 5 * HZ))
266 ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n", 293 ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",
267 command, jiffies_to_msecs(jiffies - wait_time)); 294 command, jiffies_to_msecs(jiffies - wait_time));
@@ -275,6 +302,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
275 spin_unlock_irqrestore(&ha->hardware_lock, 302 spin_unlock_irqrestore(&ha->hardware_lock,
276 flags); 303 flags);
277 ha->flags.mbox_busy = 0; 304 ha->flags.mbox_busy = 0;
305 atomic_dec(&ha->num_pend_mbx_stage2);
278 ql_dbg(ql_dbg_mbx, vha, 0x1012, 306 ql_dbg(ql_dbg_mbx, vha, 0x1012,
279 "Pending mailbox timeout, exiting.\n"); 307 "Pending mailbox timeout, exiting.\n");
280 rval = QLA_FUNCTION_TIMEOUT; 308 rval = QLA_FUNCTION_TIMEOUT;
@@ -289,6 +317,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
289 317
290 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */ 318 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
291 while (!ha->flags.mbox_int) { 319 while (!ha->flags.mbox_int) {
320 if (ha->flags.purge_mbox ||
321 chip_reset != ha->chip_reset) {
322 ha->flags.mbox_busy = 0;
323 atomic_dec(&ha->num_pend_mbx_stage2);
324 rval = QLA_ABORTED;
325 goto premature_exit;
326 }
327
292 if (time_after(jiffies, wait_time)) 328 if (time_after(jiffies, wait_time))
293 break; 329 break;
294 330
@@ -312,6 +348,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
312 "Waited %d sec.\n", 348 "Waited %d sec.\n",
313 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ)); 349 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
314 } 350 }
351 atomic_dec(&ha->num_pend_mbx_stage2);
315 352
316 /* Check whether we timed out */ 353 /* Check whether we timed out */
317 if (ha->flags.mbox_int) { 354 if (ha->flags.mbox_int) {
@@ -390,7 +427,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
390 /* Capture FW dump only, if PCI device active */ 427 /* Capture FW dump only, if PCI device active */
391 if (!pci_channel_offline(vha->hw->pdev)) { 428 if (!pci_channel_offline(vha->hw->pdev)) {
392 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); 429 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
393 if (w == 0xffff || ictrl == 0xffffffff) { 430 if (w == 0xffff || ictrl == 0xffffffff ||
431 (chip_reset != ha->chip_reset)) {
394 /* This is special case if there is unload 432 /* This is special case if there is unload
395 * of driver happening and if PCI device go 433 * of driver happening and if PCI device go
396 * into bad state due to PCI error condition 434 * into bad state due to PCI error condition
@@ -497,7 +535,11 @@ premature_exit:
497 complete(&ha->mbx_cmd_comp); 535 complete(&ha->mbx_cmd_comp);
498 536
499mbx_done: 537mbx_done:
500 if (rval) { 538 if (rval == QLA_ABORTED) {
539 ql_log(ql_log_info, vha, 0xd035,
540 "Chip Reset in progress. Purging Mbox cmd=0x%x.\n",
541 mcp->mb[0]);
542 } else if (rval) {
501 if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) { 543 if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) {
502 pr_warn("%s [%s]-%04x:%ld: **** Failed", QL_MSGHDR, 544 pr_warn("%s [%s]-%04x:%ld: **** Failed", QL_MSGHDR,
503 dev_name(&ha->pdev->dev), 0x1020+0x800, 545 dev_name(&ha->pdev->dev), 0x1020+0x800,
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index e218d68de532..04e0c7f51e68 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2815,6 +2815,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2815 ha->link_data_rate = PORT_SPEED_UNKNOWN; 2815 ha->link_data_rate = PORT_SPEED_UNKNOWN;
2816 ha->optrom_size = OPTROM_SIZE_2300; 2816 ha->optrom_size = OPTROM_SIZE_2300;
2817 ha->max_exchg = FW_MAX_EXCHANGES_CNT; 2817 ha->max_exchg = FW_MAX_EXCHANGES_CNT;
2818 atomic_set(&ha->num_pend_mbx_stage1, 0);
2819 atomic_set(&ha->num_pend_mbx_stage2, 0);
2820 atomic_set(&ha->num_pend_mbx_stage3, 0);
2818 2821
2819 /* Assign ISP specific operations. */ 2822 /* Assign ISP specific operations. */
2820 if (IS_QLA2100(ha)) { 2823 if (IS_QLA2100(ha)) {