aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Trapp <darren.trapp@cavium.com>2018-03-21 02:09:32 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2018-03-21 18:38:54 -0400
commit9dd9686b14199a1c3e668e1cca124cd1c74b77e1 (patch)
treebbeef114969ada6e37e861525e8ce7b05cc2899e
parentdbe18018e3ad60fc5abfe999b49c4b37f8e7bb32 (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.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c5
-rw-r--r--drivers/scsi/qla2xxx/qla_nvme.c142
-rw-r--r--drivers/scsi/qla2xxx/qla_nvme.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c13
-rw-r--r--drivers/scsi/qla2xxx/qla_target.h2
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
17int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) 17int 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;
188rel:
189 qla2xxx_rel_qpair_sp(sp->qpair, sp);
190} 182}
191 183
192static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport, 184static 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)
218static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, 211static 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
289static void qla_nvme_poll(struct nvme_fc_local_port *lport, void *hw_queue_handle) 281static 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)
547static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport) 539static 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
604static 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
620void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp) 601void 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
655void qla_nvme_delete(struct scsi_qla_host *vha) 637void 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
34struct nvme_rport { 37struct 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
964static void qlt_free_session_done(struct work_struct *work) 964void 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}
1178EXPORT_SYMBOL(qlt_unreg_sess); 1181EXPORT_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);
1016extern int __init qlt_init(void); 1016extern int __init qlt_init(void);
1017extern void qlt_exit(void); 1017extern void qlt_exit(void);
1018extern void qlt_update_vp_map(struct scsi_qla_host *, int); 1018extern void qlt_update_vp_map(struct scsi_qla_host *, int);
1019 1019extern 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.