diff options
author | Darren Trapp <darren.trapp@cavium.com> | 2018-03-21 02:09:32 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-03-21 18:38:54 -0400 |
commit | 9dd9686b14199a1c3e668e1cca124cd1c74b77e1 (patch) | |
tree | bbeef114969ada6e37e861525e8ce7b05cc2899e | |
parent | dbe18018e3ad60fc5abfe999b49c4b37f8e7bb32 (diff) |
scsi: qla2xxx: Add changes for devloss timeout in driver
Add support for error recovery within devloss timeout, now that
FC-NVMe transport support devloss timeout.
Signed-off-by: Darren Trapp <darren.trapp@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 8 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 5 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nvme.c | 142 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nvme.h | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 13 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.h | 2 |
7 files changed, 87 insertions, 90 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index be7d6824581a..56f78dce4d3c 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2355,6 +2355,7 @@ typedef struct fc_port { | |||
2355 | #define NVME_PRLI_SP_DISCOVERY BIT_3 | 2355 | #define NVME_PRLI_SP_DISCOVERY BIT_3 |
2356 | uint8_t nvme_flag; | 2356 | uint8_t nvme_flag; |
2357 | #define NVME_FLAG_REGISTERED 4 | 2357 | #define NVME_FLAG_REGISTERED 4 |
2358 | #define NVME_FLAG_DELETING 2 | ||
2358 | 2359 | ||
2359 | struct fc_port *conflict; | 2360 | struct fc_port *conflict; |
2360 | unsigned char logout_completed; | 2361 | unsigned char logout_completed; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 1878a6f24ddb..7f8bfa0454d2 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -5517,6 +5517,14 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) | |||
5517 | break; | 5517 | break; |
5518 | } | 5518 | } |
5519 | 5519 | ||
5520 | if (fcport->fc4f_nvme) { | ||
5521 | if (fcport->disc_state == DSC_DELETE_PEND) { | ||
5522 | fcport->disc_state = DSC_GNL; | ||
5523 | vha->fcport_count--; | ||
5524 | fcport->login_succ = 0; | ||
5525 | } | ||
5526 | } | ||
5527 | |||
5520 | if (found) { | 5528 | if (found) { |
5521 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | 5529 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); |
5522 | continue; | 5530 | continue; |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 16c43bd9bb83..93f2f1df7168 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1910,7 +1910,7 @@ qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) | |||
1910 | } else { | 1910 | } else { |
1911 | switch (le16_to_cpu(sts->comp_status)) { | 1911 | switch (le16_to_cpu(sts->comp_status)) { |
1912 | case CS_COMPLETE: | 1912 | case CS_COMPLETE: |
1913 | ret = 0; | 1913 | ret = QLA_SUCCESS; |
1914 | break; | 1914 | break; |
1915 | 1915 | ||
1916 | case CS_ABORTED: | 1916 | case CS_ABORTED: |
@@ -1922,7 +1922,8 @@ qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) | |||
1922 | "NVME-%s ERR Handling - hdl=%x completion status(%x) resid=%x ox_id=%x\n", | 1922 | "NVME-%s ERR Handling - hdl=%x completion status(%x) resid=%x ox_id=%x\n", |
1923 | sp->name, sp->handle, sts->comp_status, | 1923 | sp->name, sp->handle, sts->comp_status, |
1924 | le32_to_cpu(sts->residual_len), sts->ox_id); | 1924 | le32_to_cpu(sts->residual_len), sts->ox_id); |
1925 | fd->transferred_length = fd->payload_length; | 1925 | fd->transferred_length = 0; |
1926 | iocb->u.nvme.rsp_pyld_len = 0; | ||
1926 | ret = QLA_ABORTED; | 1927 | ret = QLA_ABORTED; |
1927 | break; | 1928 | break; |
1928 | 1929 | ||
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index 91f8b3c2afb6..5ee447680ddd 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c | |||
@@ -16,15 +16,13 @@ static void qla_nvme_unregister_remote_port(struct work_struct *); | |||
16 | 16 | ||
17 | int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) | 17 | int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) |
18 | { | 18 | { |
19 | struct nvme_rport *rport; | 19 | struct qla_nvme_rport *rport; |
20 | struct nvme_fc_port_info req; | ||
20 | int ret; | 21 | int ret; |
21 | 22 | ||
22 | if (!IS_ENABLED(CONFIG_NVME_FC)) | 23 | if (!IS_ENABLED(CONFIG_NVME_FC)) |
23 | return 0; | 24 | return 0; |
24 | 25 | ||
25 | if (fcport->nvme_flag & NVME_FLAG_REGISTERED) | ||
26 | return 0; | ||
27 | |||
28 | if (!vha->flags.nvme_enabled) { | 26 | if (!vha->flags.nvme_enabled) { |
29 | ql_log(ql_log_info, vha, 0x2100, | 27 | ql_log(ql_log_info, vha, 0x2100, |
30 | "%s: Not registering target since Host NVME is not enabled\n", | 28 | "%s: Not registering target since Host NVME is not enabled\n", |
@@ -33,38 +31,35 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) | |||
33 | } | 31 | } |
34 | 32 | ||
35 | if (!(fcport->nvme_prli_service_param & | 33 | if (!(fcport->nvme_prli_service_param & |
36 | (NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY))) | 34 | (NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)) || |
35 | (fcport->nvme_flag & NVME_FLAG_REGISTERED)) | ||
37 | return 0; | 36 | return 0; |
38 | 37 | ||
39 | INIT_WORK(&fcport->nvme_del_work, qla_nvme_unregister_remote_port); | 38 | INIT_WORK(&fcport->nvme_del_work, qla_nvme_unregister_remote_port); |
40 | rport = kzalloc(sizeof(*rport), GFP_KERNEL); | ||
41 | if (!rport) { | ||
42 | ql_log(ql_log_warn, vha, 0x2101, | ||
43 | "%s: unable to alloc memory\n", __func__); | ||
44 | return -ENOMEM; | ||
45 | } | ||
46 | 39 | ||
47 | rport->req.port_name = wwn_to_u64(fcport->port_name); | 40 | memset(&req, 0, sizeof(struct nvme_fc_port_info)); |
48 | rport->req.node_name = wwn_to_u64(fcport->node_name); | 41 | req.port_name = wwn_to_u64(fcport->port_name); |
49 | rport->req.port_role = 0; | 42 | req.node_name = wwn_to_u64(fcport->node_name); |
43 | req.port_role = 0; | ||
44 | req.dev_loss_tmo = NVME_FC_DEV_LOSS_TMO; | ||
50 | 45 | ||
51 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR) | 46 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR) |
52 | rport->req.port_role = FC_PORT_ROLE_NVME_INITIATOR; | 47 | req.port_role = FC_PORT_ROLE_NVME_INITIATOR; |
53 | 48 | ||
54 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_TARGET) | 49 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_TARGET) |
55 | rport->req.port_role |= FC_PORT_ROLE_NVME_TARGET; | 50 | req.port_role |= FC_PORT_ROLE_NVME_TARGET; |
56 | 51 | ||
57 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_DISCOVERY) | 52 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_DISCOVERY) |
58 | rport->req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY; | 53 | req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY; |
59 | 54 | ||
60 | rport->req.port_id = fcport->d_id.b24; | 55 | req.port_id = fcport->d_id.b24; |
61 | 56 | ||
62 | ql_log(ql_log_info, vha, 0x2102, | 57 | ql_log(ql_log_info, vha, 0x2102, |
63 | "%s: traddr=nn-0x%016llx:pn-0x%016llx PortID:%06x\n", | 58 | "%s: traddr=nn-0x%016llx:pn-0x%016llx PortID:%06x\n", |
64 | __func__, rport->req.node_name, rport->req.port_name, | 59 | __func__, req.node_name, req.port_name, |
65 | rport->req.port_id); | 60 | req.port_id); |
66 | 61 | ||
67 | ret = nvme_fc_register_remoteport(vha->nvme_local_port, &rport->req, | 62 | ret = nvme_fc_register_remoteport(vha->nvme_local_port, &req, |
68 | &fcport->nvme_remote_port); | 63 | &fcport->nvme_remote_port); |
69 | if (ret) { | 64 | if (ret) { |
70 | ql_log(ql_log_warn, vha, 0x212e, | 65 | ql_log(ql_log_warn, vha, 0x212e, |
@@ -73,10 +68,11 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) | |||
73 | return ret; | 68 | return ret; |
74 | } | 69 | } |
75 | 70 | ||
76 | fcport->nvme_remote_port->private = fcport; | 71 | rport = fcport->nvme_remote_port->private; |
77 | fcport->nvme_flag |= NVME_FLAG_REGISTERED; | ||
78 | rport->fcport = fcport; | 72 | rport->fcport = fcport; |
79 | list_add_tail(&rport->list, &vha->nvme_rport_list); | 73 | list_add_tail(&rport->list, &vha->nvme_rport_list); |
74 | |||
75 | fcport->nvme_flag |= NVME_FLAG_REGISTERED; | ||
80 | return 0; | 76 | return 0; |
81 | } | 77 | } |
82 | 78 | ||
@@ -174,26 +170,23 @@ static void qla_nvme_sp_done(void *ptr, int res) | |||
174 | if (!atomic_dec_and_test(&sp->ref_count)) | 170 | if (!atomic_dec_and_test(&sp->ref_count)) |
175 | return; | 171 | return; |
176 | 172 | ||
177 | if (!(sp->fcport->nvme_flag & NVME_FLAG_REGISTERED)) | 173 | if (res == QLA_SUCCESS) |
178 | goto rel; | ||
179 | |||
180 | if (unlikely(res == QLA_FUNCTION_FAILED)) | ||
181 | fd->status = NVME_SC_INTERNAL; | ||
182 | else | ||
183 | fd->status = 0; | 174 | fd->status = 0; |
175 | else | ||
176 | fd->status = NVME_SC_INTERNAL; | ||
184 | 177 | ||
185 | fd->rcv_rsplen = nvme->u.nvme.rsp_pyld_len; | 178 | fd->rcv_rsplen = nvme->u.nvme.rsp_pyld_len; |
186 | list_add_tail(&nvme->u.nvme.entry, &sp->qpair->nvme_done_list); | 179 | list_add_tail(&nvme->u.nvme.entry, &sp->qpair->nvme_done_list); |
180 | |||
187 | return; | 181 | return; |
188 | rel: | ||
189 | qla2xxx_rel_qpair_sp(sp->qpair, sp); | ||
190 | } | 182 | } |
191 | 183 | ||
192 | static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport, | 184 | static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport, |
193 | struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd) | 185 | struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd) |
194 | { | 186 | { |
195 | struct nvme_private *priv = fd->private; | 187 | struct nvme_private *priv = fd->private; |
196 | fc_port_t *fcport = rport->private; | 188 | struct qla_nvme_rport *qla_rport = rport->private; |
189 | fc_port_t *fcport = qla_rport->fcport; | ||
197 | srb_t *sp = priv->sp; | 190 | srb_t *sp = priv->sp; |
198 | int rval; | 191 | int rval; |
199 | struct qla_hw_data *ha = fcport->vha->hw; | 192 | struct qla_hw_data *ha = fcport->vha->hw; |
@@ -218,7 +211,8 @@ static void qla_nvme_ls_complete(struct work_struct *work) | |||
218 | static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, | 211 | static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, |
219 | struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd) | 212 | struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd) |
220 | { | 213 | { |
221 | fc_port_t *fcport = rport->private; | 214 | struct qla_nvme_rport *qla_rport = rport->private; |
215 | fc_port_t *fcport = qla_rport->fcport; | ||
222 | struct srb_iocb *nvme; | 216 | struct srb_iocb *nvme; |
223 | struct nvme_private *priv = fd->private; | 217 | struct nvme_private *priv = fd->private; |
224 | struct scsi_qla_host *vha; | 218 | struct scsi_qla_host *vha; |
@@ -226,9 +220,6 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, | |||
226 | struct qla_hw_data *ha; | 220 | struct qla_hw_data *ha; |
227 | srb_t *sp; | 221 | srb_t *sp; |
228 | 222 | ||
229 | if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED)) | ||
230 | return rval; | ||
231 | |||
232 | vha = fcport->vha; | 223 | vha = fcport->vha; |
233 | ha = vha->hw; | 224 | ha = vha->hw; |
234 | /* Alloc SRB structure */ | 225 | /* Alloc SRB structure */ |
@@ -275,7 +266,8 @@ static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport, | |||
275 | struct nvme_private *priv = fd->private; | 266 | struct nvme_private *priv = fd->private; |
276 | srb_t *sp = priv->sp; | 267 | srb_t *sp = priv->sp; |
277 | int rval; | 268 | int rval; |
278 | fc_port_t *fcport = rport->private; | 269 | struct qla_nvme_rport *qla_rport = rport->private; |
270 | fc_port_t *fcport = qla_rport->fcport; | ||
279 | struct qla_hw_data *ha = fcport->vha->hw; | 271 | struct qla_hw_data *ha = fcport->vha->hw; |
280 | 272 | ||
281 | rval = ha->isp_ops->abort_command(sp); | 273 | rval = ha->isp_ops->abort_command(sp); |
@@ -288,11 +280,10 @@ static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport, | |||
288 | 280 | ||
289 | static void qla_nvme_poll(struct nvme_fc_local_port *lport, void *hw_queue_handle) | 281 | static void qla_nvme_poll(struct nvme_fc_local_port *lport, void *hw_queue_handle) |
290 | { | 282 | { |
291 | struct scsi_qla_host *vha = lport->private; | ||
292 | unsigned long flags; | ||
293 | struct qla_qpair *qpair = hw_queue_handle; | 283 | struct qla_qpair *qpair = hw_queue_handle; |
284 | unsigned long flags; | ||
285 | struct scsi_qla_host *vha = lport->private; | ||
294 | 286 | ||
295 | /* Acquire ring specific lock */ | ||
296 | spin_lock_irqsave(&qpair->qp_lock, flags); | 287 | spin_lock_irqsave(&qpair->qp_lock, flags); |
297 | qla24xx_process_response_queue(vha, qpair->rsp); | 288 | qla24xx_process_response_queue(vha, qpair->rsp); |
298 | spin_unlock_irqrestore(&qpair->qp_lock, flags); | 289 | spin_unlock_irqrestore(&qpair->qp_lock, flags); |
@@ -490,6 +481,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, | |||
490 | srb_t *sp; | 481 | srb_t *sp; |
491 | struct qla_qpair *qpair = hw_queue_handle; | 482 | struct qla_qpair *qpair = hw_queue_handle; |
492 | struct nvme_private *priv; | 483 | struct nvme_private *priv; |
484 | struct qla_nvme_rport *qla_rport = rport->private; | ||
493 | 485 | ||
494 | if (!fd) { | 486 | if (!fd) { |
495 | ql_log(ql_log_warn, NULL, 0x2134, "NO NVMe FCP request\n"); | 487 | ql_log(ql_log_warn, NULL, 0x2134, "NO NVMe FCP request\n"); |
@@ -497,14 +489,14 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, | |||
497 | } | 489 | } |
498 | 490 | ||
499 | priv = fd->private; | 491 | priv = fd->private; |
500 | fcport = rport->private; | 492 | fcport = qla_rport->fcport; |
501 | if (!fcport) { | 493 | if (!fcport) { |
502 | ql_log(ql_log_warn, NULL, 0x210e, "No fcport ptr\n"); | 494 | ql_log(ql_log_warn, NULL, 0x210e, "No fcport ptr\n"); |
503 | return rval; | 495 | return rval; |
504 | } | 496 | } |
505 | 497 | ||
506 | vha = fcport->vha; | 498 | vha = fcport->vha; |
507 | if ((!qpair) || (!(fcport->nvme_flag & NVME_FLAG_REGISTERED))) | 499 | if (!qpair) |
508 | return -EBUSY; | 500 | return -EBUSY; |
509 | 501 | ||
510 | /* Alloc SRB structure */ | 502 | /* Alloc SRB structure */ |
@@ -547,22 +539,27 @@ static void qla_nvme_localport_delete(struct nvme_fc_local_port *lport) | |||
547 | static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport) | 539 | static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport) |
548 | { | 540 | { |
549 | fc_port_t *fcport; | 541 | fc_port_t *fcport; |
550 | struct nvme_rport *r_port, *trport; | 542 | struct qla_nvme_rport *qla_rport = rport->private, *trport; |
551 | 543 | ||
552 | fcport = rport->private; | 544 | fcport = qla_rport->fcport; |
553 | fcport->nvme_remote_port = NULL; | 545 | fcport->nvme_remote_port = NULL; |
554 | fcport->nvme_flag &= ~NVME_FLAG_REGISTERED; | 546 | fcport->nvme_flag &= ~NVME_FLAG_REGISTERED; |
555 | 547 | ||
556 | list_for_each_entry_safe(r_port, trport, | 548 | list_for_each_entry_safe(qla_rport, trport, |
557 | &fcport->vha->nvme_rport_list, list) { | 549 | &fcport->vha->nvme_rport_list, list) { |
558 | if (r_port->fcport == fcport) { | 550 | if (qla_rport->fcport == fcport) { |
559 | list_del(&r_port->list); | 551 | list_del(&qla_rport->list); |
560 | break; | 552 | break; |
561 | } | 553 | } |
562 | } | 554 | } |
563 | kfree(r_port); | ||
564 | complete(&fcport->nvme_del_done); | 555 | complete(&fcport->nvme_del_done); |
565 | 556 | ||
557 | if (!test_bit(UNLOADING, &fcport->vha->dpc_flags)) { | ||
558 | INIT_WORK(&fcport->free_work, qlt_free_session_done); | ||
559 | schedule_work(&fcport->free_work); | ||
560 | } | ||
561 | |||
562 | fcport->nvme_flag &= ~(NVME_FLAG_REGISTERED | NVME_FLAG_DELETING); | ||
566 | ql_log(ql_log_info, fcport->vha, 0x2110, | 563 | ql_log(ql_log_info, fcport->vha, 0x2110, |
567 | "remoteport_delete of %p completed.\n", fcport); | 564 | "remoteport_delete of %p completed.\n", fcport); |
568 | } | 565 | } |
@@ -582,7 +579,7 @@ static struct nvme_fc_port_template qla_nvme_fc_transport = { | |||
582 | .max_dif_sgl_segments = 64, | 579 | .max_dif_sgl_segments = 64, |
583 | .dma_boundary = 0xFFFFFFFF, | 580 | .dma_boundary = 0xFFFFFFFF, |
584 | .local_priv_sz = 8, | 581 | .local_priv_sz = 8, |
585 | .remote_priv_sz = 0, | 582 | .remote_priv_sz = sizeof(struct qla_nvme_rport), |
586 | .lsrqst_priv_sz = sizeof(struct nvme_private), | 583 | .lsrqst_priv_sz = sizeof(struct nvme_private), |
587 | .fcprqst_priv_sz = sizeof(struct nvme_private), | 584 | .fcprqst_priv_sz = sizeof(struct nvme_private), |
588 | }; | 585 | }; |
@@ -601,22 +598,6 @@ static int qla_nvme_wait_on_command(srb_t *sp) | |||
601 | return ret; | 598 | return ret; |
602 | } | 599 | } |
603 | 600 | ||
604 | static int qla_nvme_wait_on_rport_del(fc_port_t *fcport) | ||
605 | { | ||
606 | int ret = QLA_SUCCESS; | ||
607 | int timeout; | ||
608 | |||
609 | timeout = wait_for_completion_timeout(&fcport->nvme_del_done, | ||
610 | msecs_to_jiffies(2000)); | ||
611 | if (!timeout) { | ||
612 | ret = QLA_FUNCTION_FAILED; | ||
613 | ql_log(ql_log_info, fcport->vha, 0x2111, | ||
614 | "timed out waiting for fcport=%p to delete\n", fcport); | ||
615 | } | ||
616 | |||
617 | return ret; | ||
618 | } | ||
619 | |||
620 | void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp) | 601 | void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp) |
621 | { | 602 | { |
622 | int rval; | 603 | int rval; |
@@ -631,7 +612,7 @@ static void qla_nvme_unregister_remote_port(struct work_struct *work) | |||
631 | { | 612 | { |
632 | struct fc_port *fcport = container_of(work, struct fc_port, | 613 | struct fc_port *fcport = container_of(work, struct fc_port, |
633 | nvme_del_work); | 614 | nvme_del_work); |
634 | struct nvme_rport *rport, *trport; | 615 | struct qla_nvme_rport *qla_rport, *trport; |
635 | 616 | ||
636 | if (!IS_ENABLED(CONFIG_NVME_FC)) | 617 | if (!IS_ENABLED(CONFIG_NVME_FC)) |
637 | return; | 618 | return; |
@@ -639,51 +620,52 @@ static void qla_nvme_unregister_remote_port(struct work_struct *work) | |||
639 | ql_log(ql_log_warn, NULL, 0x2112, | 620 | ql_log(ql_log_warn, NULL, 0x2112, |
640 | "%s: unregister remoteport on %p\n",__func__, fcport); | 621 | "%s: unregister remoteport on %p\n",__func__, fcport); |
641 | 622 | ||
642 | list_for_each_entry_safe(rport, trport, | 623 | list_for_each_entry_safe(qla_rport, trport, |
643 | &fcport->vha->nvme_rport_list, list) { | 624 | &fcport->vha->nvme_rport_list, list) { |
644 | if (rport->fcport == fcport) { | 625 | if (qla_rport->fcport == fcport) { |
645 | ql_log(ql_log_info, fcport->vha, 0x2113, | 626 | ql_log(ql_log_info, fcport->vha, 0x2113, |
646 | "%s: fcport=%p\n", __func__, fcport); | 627 | "%s: fcport=%p\n", __func__, fcport); |
647 | init_completion(&fcport->nvme_del_done); | 628 | init_completion(&fcport->nvme_del_done); |
648 | nvme_fc_unregister_remoteport( | 629 | nvme_fc_unregister_remoteport( |
649 | fcport->nvme_remote_port); | 630 | fcport->nvme_remote_port); |
650 | qla_nvme_wait_on_rport_del(fcport); | 631 | wait_for_completion(&fcport->nvme_del_done); |
632 | break; | ||
651 | } | 633 | } |
652 | } | 634 | } |
653 | } | 635 | } |
654 | 636 | ||
655 | void qla_nvme_delete(struct scsi_qla_host *vha) | 637 | void qla_nvme_delete(struct scsi_qla_host *vha) |
656 | { | 638 | { |
657 | struct nvme_rport *rport, *trport; | 639 | struct qla_nvme_rport *qla_rport, *trport; |
658 | fc_port_t *fcport; | 640 | fc_port_t *fcport; |
659 | int nv_ret; | 641 | int nv_ret; |
660 | 642 | ||
661 | if (!IS_ENABLED(CONFIG_NVME_FC)) | 643 | if (!IS_ENABLED(CONFIG_NVME_FC)) |
662 | return; | 644 | return; |
663 | 645 | ||
664 | list_for_each_entry_safe(rport, trport, &vha->nvme_rport_list, list) { | 646 | list_for_each_entry_safe(qla_rport, trport, |
665 | fcport = rport->fcport; | 647 | &vha->nvme_rport_list, list) { |
648 | fcport = qla_rport->fcport; | ||
666 | 649 | ||
667 | ql_log(ql_log_info, fcport->vha, 0x2114, "%s: fcport=%p\n", | 650 | ql_log(ql_log_info, fcport->vha, 0x2114, "%s: fcport=%p\n", |
668 | __func__, fcport); | 651 | __func__, fcport); |
669 | 652 | ||
670 | init_completion(&fcport->nvme_del_done); | 653 | init_completion(&fcport->nvme_del_done); |
671 | nvme_fc_unregister_remoteport(fcport->nvme_remote_port); | 654 | nvme_fc_unregister_remoteport(fcport->nvme_remote_port); |
672 | qla_nvme_wait_on_rport_del(fcport); | 655 | wait_for_completion(&fcport->nvme_del_done); |
673 | } | 656 | } |
674 | 657 | ||
675 | if (vha->nvme_local_port) { | 658 | if (vha->nvme_local_port) { |
676 | init_completion(&vha->nvme_del_done); | 659 | init_completion(&vha->nvme_del_done); |
660 | ql_log(ql_log_info, vha, 0x2116, | ||
661 | "unregister localport=%p\n", | ||
662 | vha->nvme_local_port); | ||
677 | nv_ret = nvme_fc_unregister_localport(vha->nvme_local_port); | 663 | nv_ret = nvme_fc_unregister_localport(vha->nvme_local_port); |
678 | if (nv_ret == 0) | 664 | if (nv_ret) |
679 | ql_log(ql_log_info, vha, 0x2116, | ||
680 | "unregistered localport=%p\n", | ||
681 | vha->nvme_local_port); | ||
682 | else | ||
683 | ql_log(ql_log_info, vha, 0x2115, | 665 | ql_log(ql_log_info, vha, 0x2115, |
684 | "Unregister of localport failed\n"); | 666 | "Unregister of localport failed\n"); |
685 | wait_for_completion_timeout(&vha->nvme_del_done, | 667 | else |
686 | msecs_to_jiffies(5000)); | 668 | wait_for_completion(&vha->nvme_del_done); |
687 | } | 669 | } |
688 | } | 670 | } |
689 | 671 | ||
diff --git a/drivers/scsi/qla2xxx/qla_nvme.h b/drivers/scsi/qla2xxx/qla_nvme.h index 7f05fa1c77db..7becfc1b3e69 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.h +++ b/drivers/scsi/qla2xxx/qla_nvme.h | |||
@@ -14,6 +14,9 @@ | |||
14 | 14 | ||
15 | #include "qla_def.h" | 15 | #include "qla_def.h" |
16 | 16 | ||
17 | /* default dev loss time (seconds) before transport tears down ctrl */ | ||
18 | #define NVME_FC_DEV_LOSS_TMO 30 | ||
19 | |||
17 | #define NVME_ATIO_CMD_OFF 32 | 20 | #define NVME_ATIO_CMD_OFF 32 |
18 | #define NVME_FIRST_PACKET_CMDLEN (64 - NVME_ATIO_CMD_OFF) | 21 | #define NVME_FIRST_PACKET_CMDLEN (64 - NVME_ATIO_CMD_OFF) |
19 | #define Q2T_NVME_NUM_TAGS 2048 | 22 | #define Q2T_NVME_NUM_TAGS 2048 |
@@ -31,8 +34,7 @@ struct nvme_private { | |||
31 | int comp_status; | 34 | int comp_status; |
32 | }; | 35 | }; |
33 | 36 | ||
34 | struct nvme_rport { | 37 | struct qla_nvme_rport { |
35 | struct nvme_fc_port_info req; | ||
36 | struct list_head list; | 38 | struct list_head list; |
37 | struct fc_port *fcport; | 39 | struct fc_port *fcport; |
38 | }; | 40 | }; |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 41863a056c9a..ead6813ea9b3 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -961,7 +961,7 @@ qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo) | |||
961 | logo->cmd_count, res); | 961 | logo->cmd_count, res); |
962 | } | 962 | } |
963 | 963 | ||
964 | static void qlt_free_session_done(struct work_struct *work) | 964 | void qlt_free_session_done(struct work_struct *work) |
965 | { | 965 | { |
966 | struct fc_port *sess = container_of(work, struct fc_port, | 966 | struct fc_port *sess = container_of(work, struct fc_port, |
967 | free_work); | 967 | free_work); |
@@ -1169,11 +1169,14 @@ void qlt_unreg_sess(struct fc_port *sess) | |||
1169 | sess->last_rscn_gen = sess->rscn_gen; | 1169 | sess->last_rscn_gen = sess->rscn_gen; |
1170 | sess->last_login_gen = sess->login_gen; | 1170 | sess->last_login_gen = sess->login_gen; |
1171 | 1171 | ||
1172 | if (sess->nvme_flag & NVME_FLAG_REGISTERED) | 1172 | if (sess->nvme_flag & NVME_FLAG_REGISTERED && |
1173 | !(sess->nvme_flag & NVME_FLAG_DELETING)) { | ||
1174 | sess->nvme_flag |= NVME_FLAG_DELETING; | ||
1173 | schedule_work(&sess->nvme_del_work); | 1175 | schedule_work(&sess->nvme_del_work); |
1174 | 1176 | } else { | |
1175 | INIT_WORK(&sess->free_work, qlt_free_session_done); | 1177 | INIT_WORK(&sess->free_work, qlt_free_session_done); |
1176 | schedule_work(&sess->free_work); | 1178 | schedule_work(&sess->free_work); |
1179 | } | ||
1177 | } | 1180 | } |
1178 | EXPORT_SYMBOL(qlt_unreg_sess); | 1181 | EXPORT_SYMBOL(qlt_unreg_sess); |
1179 | 1182 | ||
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index bb67b5a284a8..728ce74358e7 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
@@ -1016,7 +1016,7 @@ extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *, int); | |||
1016 | extern int __init qlt_init(void); | 1016 | extern int __init qlt_init(void); |
1017 | extern void qlt_exit(void); | 1017 | extern void qlt_exit(void); |
1018 | extern void qlt_update_vp_map(struct scsi_qla_host *, int); | 1018 | extern void qlt_update_vp_map(struct scsi_qla_host *, int); |
1019 | 1019 | extern void qlt_free_session_done(struct work_struct *); | |
1020 | /* | 1020 | /* |
1021 | * This macro is used during early initializations when host->active_mode | 1021 | * This macro is used during early initializations when host->active_mode |
1022 | * is not set. Right now, ha value is ignored. | 1022 | * is not set. Right now, ha value is ignored. |