Daniel Wagner 1bf4db
From: Quinn Tran <qutran@marvell.com>
Daniel Wagner 1bf4db
Date: Mon, 6 Jun 2022 21:46:17 -0700
Daniel Wagner 1bf4db
Subject: scsi: qla2xxx: edif: Reduce Initiator-Initiator thrashing
Denis Kirjanov 718367
Patch-mainline: v5.20-rc1
Daniel Wagner 1bf4db
Git-commit: 9c40c36e75ffd49952cd4ead0672defc4b4dbdf7
Daniel Wagner 1bf4db
References: bsc#1201958
Daniel Wagner 1bf4db
Daniel Wagner 1bf4db
This patch uses GFFID switch command to scan whether remote device is
Daniel Wagner 1bf4db
Target or Initiator mode.  Based on that info, driver will not pass up
Daniel Wagner 1bf4db
Initiator info to authentication application. This helps reduce unnecessary
Daniel Wagner 1bf4db
stress for authentication application to deal with unused connections.
Daniel Wagner 1bf4db
Daniel Wagner 1bf4db
Link: https://lore.kernel.org/r/20220607044627.19563-2-njavali@marvell.com
Daniel Wagner 1bf4db
Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs")
Daniel Wagner 1bf4db
Signed-off-by: Quinn Tran <qutran@marvell.com>
Daniel Wagner 1bf4db
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Daniel Wagner 1bf4db
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Daniel Wagner 1bf4db
Acked-by: Daniel Wagner <dwagner@suse.de>
Daniel Wagner 1bf4db
---
Daniel Wagner 1bf4db
 drivers/scsi/qla2xxx/qla_def.h  |    2 
Daniel Wagner 1bf4db
 drivers/scsi/qla2xxx/qla_edif.c |   32 +++++++++-
Daniel Wagner 1bf4db
 drivers/scsi/qla2xxx/qla_gbl.h  |    3 -
Daniel Wagner 1bf4db
 drivers/scsi/qla2xxx/qla_gs.c   |  118 +++++++++++++++++++++++++++++-----------
Daniel Wagner 1bf4db
 drivers/scsi/qla2xxx/qla_iocb.c |    2 
Daniel Wagner 1bf4db
 5 files changed, 120 insertions(+), 37 deletions(-)
Daniel Wagner 1bf4db
Daniel Wagner 1bf4db
--- a/drivers/scsi/qla2xxx/qla_def.h
Daniel Wagner 1bf4db
+++ b/drivers/scsi/qla2xxx/qla_def.h
Daniel Wagner 1bf4db
@@ -3205,6 +3205,8 @@ struct ct_sns_rsp {
Daniel Wagner 1bf4db
 #define GFF_NVME_OFFSET		23 /* type = 28h */
Daniel Wagner 1bf4db
 		struct {
Daniel Wagner 1bf4db
 			uint8_t fc4_features[128];
Daniel Wagner 1bf4db
+#define FC4_FF_TARGET    BIT_0
Daniel Wagner 1bf4db
+#define FC4_FF_INITIATOR BIT_1
Daniel Wagner 1bf4db
 		} gff_id;
Daniel Wagner 1bf4db
 		struct {
Daniel Wagner 1bf4db
 			uint8_t reserved;
Daniel Wagner 1bf4db
--- a/drivers/scsi/qla2xxx/qla_edif.c
Daniel Wagner 1bf4db
+++ b/drivers/scsi/qla2xxx/qla_edif.c
Daniel Wagner 1bf4db
@@ -517,16 +517,28 @@ qla_edif_app_start(scsi_qla_host_t *vha,
Daniel Wagner 1bf4db
 			if (atomic_read(&vha->loop_state) == LOOP_DOWN)
Daniel Wagner 1bf4db
 				break;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-			fcport->edif.app_started = 1;
Daniel Wagner 1bf4db
 			fcport->login_retry = vha->hw->login_retry_count;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-			/* no activity */
Daniel Wagner 1bf4db
 			fcport->edif.app_stop = 0;
Daniel Wagner 1bf4db
+			fcport->edif.app_sess_online = 0;
Daniel Wagner 1bf4db
+			fcport->edif.app_started = 1;
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+			if (fcport->scan_state != QLA_FCPORT_FOUND)
Daniel Wagner 1bf4db
+				continue;
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+			if (fcport->port_type == FCT_UNKNOWN &&
Daniel Wagner 1bf4db
+			    !fcport->fc4_features)
Daniel Wagner 1bf4db
+				rval = qla24xx_async_gffid(vha, fcport, true);
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+			if (!rval && !(fcport->fc4_features & FC4_FF_TARGET ||
Daniel Wagner 1bf4db
+			    fcport->port_type & (FCT_TARGET|FCT_NVME_TARGET)))
Daniel Wagner 1bf4db
+				continue;
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+			rval = 0;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
 			ql_dbg(ql_dbg_edif, vha, 0x911e,
Daniel Wagner 1bf4db
 			       "%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
Daniel Wagner 1bf4db
 			       __func__, fcport->port_name);
Daniel Wagner 1bf4db
-			fcport->edif.app_sess_online = 0;
Daniel Wagner 1bf4db
 			qlt_schedule_sess_for_deletion(fcport);
Daniel Wagner 1bf4db
 			qla_edif_sa_ctl_init(vha, fcport);
Daniel Wagner 1bf4db
 		}
Daniel Wagner 1bf4db
@@ -883,6 +895,20 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *
Daniel Wagner 1bf4db
 			app_reply->ports[pcnt].rekey_count =
Daniel Wagner 1bf4db
 				fcport->edif.rekey_cnt;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
+			if (fcport->scan_state != QLA_FCPORT_FOUND)
Daniel Wagner 1bf4db
+				continue;
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+			if (fcport->port_type == FCT_UNKNOWN && !fcport->fc4_features)
Daniel Wagner 1bf4db
+				rval = qla24xx_async_gffid(vha, fcport, true);
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+			if (!rval &&
Daniel Wagner 1bf4db
+			    !(fcport->fc4_features & FC4_FF_TARGET ||
Daniel Wagner 1bf4db
+			      fcport->port_type &
Daniel Wagner 1bf4db
+			      (FCT_TARGET | FCT_NVME_TARGET)))
Daniel Wagner 1bf4db
+				continue;
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+			rval = 0;
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
 			app_reply->ports[pcnt].remote_type =
Daniel Wagner 1bf4db
 				VND_CMD_RTYPE_UNKNOWN;
Daniel Wagner 1bf4db
 			if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET))
Daniel Wagner 1bf4db
--- a/drivers/scsi/qla2xxx/qla_gbl.h
Daniel Wagner 1bf4db
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
Daniel Wagner 1bf4db
@@ -337,6 +337,7 @@ extern int qla24xx_configure_prot_mode(s
Daniel Wagner 1bf4db
 extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha,
Daniel Wagner 1bf4db
 	struct qla_work_evt *e);
Daniel Wagner 1bf4db
 void qla2x00_sp_release(struct kref *kref);
Daniel Wagner 1bf4db
+void qla2x00_els_dcmd2_iocb_timeout(void *data);
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
 /*
Daniel Wagner 1bf4db
  * Global Function Prototypes in qla_mbx.c source file.
Daniel Wagner 1bf4db
@@ -729,7 +730,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *
Daniel Wagner 1bf4db
 void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *);
Daniel Wagner 1bf4db
 int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
Daniel Wagner 1bf4db
 void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea);
Daniel Wagner 1bf4db
-int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport);
Daniel Wagner 1bf4db
+int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool);
Daniel Wagner 1bf4db
 int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *);
Daniel Wagner 1bf4db
 void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *);
Daniel Wagner 1bf4db
 void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *);
Daniel Wagner 1bf4db
--- a/drivers/scsi/qla2xxx/qla_gs.c
Daniel Wagner 1bf4db
+++ b/drivers/scsi/qla2xxx/qla_gs.c
Daniel Wagner 1bf4db
@@ -3281,19 +3281,12 @@ int qla24xx_async_gpnid(scsi_qla_host_t
Daniel Wagner 1bf4db
 	return rval;
Daniel Wagner 1bf4db
 }
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
Daniel Wagner 1bf4db
-{
Daniel Wagner 1bf4db
-	fc_port_t *fcport = ea->fcport;
Daniel Wagner 1bf4db
-
Daniel Wagner 1bf4db
-	qla24xx_post_gnl_work(vha, fcport);
Daniel Wagner 1bf4db
-}
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
 void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
Daniel Wagner 1bf4db
 {
Daniel Wagner 1bf4db
 	struct scsi_qla_host *vha = sp->vha;
Daniel Wagner 1bf4db
 	fc_port_t *fcport = sp->fcport;
Daniel Wagner 1bf4db
 	struct ct_sns_rsp *ct_rsp;
Daniel Wagner 1bf4db
-	struct event_arg ea;
Daniel Wagner 1bf4db
 	uint8_t fc4_scsi_feat;
Daniel Wagner 1bf4db
 	uint8_t fc4_nvme_feat;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
@@ -3301,10 +3294,10 @@ void qla24xx_async_gffid_sp_done(srb_t *
Daniel Wagner 1bf4db
 	       "Async done-%s res %x ID %x. %8phC\n",
Daniel Wagner 1bf4db
 	       sp->name, res, fcport->d_id.b24, fcport->port_name);
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-	fcport->flags &= ~FCF_ASYNC_SENT;
Daniel Wagner 1bf4db
-	ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
Daniel Wagner 1bf4db
+	ct_rsp = sp->u.iocb_cmd.u.ctarg.rsp;
Daniel Wagner 1bf4db
 	fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
Daniel Wagner 1bf4db
 	fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
Daniel Wagner 1bf4db
+	sp->rc = res;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
 	/*
Daniel Wagner 1bf4db
 	 * FC-GS-7, 5.2.3.12 FC-4 Features - format
Daniel Wagner 1bf4db
@@ -3325,24 +3318,42 @@ void qla24xx_async_gffid_sp_done(srb_t *
Daniel Wagner 1bf4db
 		}
Daniel Wagner 1bf4db
 	}
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-	memset(&ea, 0, sizeof(ea));
Daniel Wagner 1bf4db
-	ea.sp = sp;
Daniel Wagner 1bf4db
-	ea.fcport = sp->fcport;
Daniel Wagner 1bf4db
-	ea.rc = res;
Daniel Wagner 1bf4db
+	if (sp->flags & SRB_WAKEUP_ON_COMP) {
Daniel Wagner 1bf4db
+		complete(sp->comp);
Daniel Wagner 1bf4db
+	} else  {
Daniel Wagner 1bf4db
+		if (sp->u.iocb_cmd.u.ctarg.req) {
Daniel Wagner 1bf4db
+			dma_free_coherent(&vha->hw->pdev->dev,
Daniel Wagner 1bf4db
+				sp->u.iocb_cmd.u.ctarg.req_allocated_size,
Daniel Wagner 1bf4db
+				sp->u.iocb_cmd.u.ctarg.req,
Daniel Wagner 1bf4db
+				sp->u.iocb_cmd.u.ctarg.req_dma);
Daniel Wagner 1bf4db
+			sp->u.iocb_cmd.u.ctarg.req = NULL;
Daniel Wagner 1bf4db
+		}
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-	qla24xx_handle_gffid_event(vha, &ea);
Daniel Wagner 1bf4db
-	/* ref: INIT */
Daniel Wagner 1bf4db
-	kref_put(&sp->cmd_kref, qla2x00_sp_release);
Daniel Wagner 1bf4db
+		if (sp->u.iocb_cmd.u.ctarg.rsp) {
Daniel Wagner 1bf4db
+			dma_free_coherent(&vha->hw->pdev->dev,
Daniel Wagner 1bf4db
+				sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
Daniel Wagner 1bf4db
+				sp->u.iocb_cmd.u.ctarg.rsp,
Daniel Wagner 1bf4db
+				sp->u.iocb_cmd.u.ctarg.rsp_dma);
Daniel Wagner 1bf4db
+			sp->u.iocb_cmd.u.ctarg.rsp = NULL;
Daniel Wagner 1bf4db
+		}
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+		/* ref: INIT */
Daniel Wagner 1bf4db
+		kref_put(&sp->cmd_kref, qla2x00_sp_release);
Daniel Wagner 1bf4db
+		/* we should not be here */
Daniel Wagner 1bf4db
+		dump_stack();
Daniel Wagner 1bf4db
+	}
Daniel Wagner 1bf4db
 }
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
 /* Get FC4 Feature with Nport ID. */
Daniel Wagner 1bf4db
-int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
Daniel Wagner 1bf4db
+int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait)
Daniel Wagner 1bf4db
 {
Daniel Wagner 1bf4db
 	int rval = QLA_FUNCTION_FAILED;
Daniel Wagner 1bf4db
 	struct ct_sns_req       *ct_req;
Daniel Wagner 1bf4db
 	srb_t *sp;
Daniel Wagner 1bf4db
+	DECLARE_COMPLETION_ONSTACK(comp);
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-	if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
Daniel Wagner 1bf4db
+	/* this routine does not have handling for no wait */
Daniel Wagner 1bf4db
+	if (!vha->flags.online || !wait)
Daniel Wagner 1bf4db
 		return rval;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
 	/* ref: INIT */
Daniel Wagner 1bf4db
@@ -3350,43 +3361,86 @@ int qla24xx_async_gffid(scsi_qla_host_t
Daniel Wagner 1bf4db
 	if (!sp)
Daniel Wagner 1bf4db
 		return rval;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-	fcport->flags |= FCF_ASYNC_SENT;
Daniel Wagner 1bf4db
 	sp->type = SRB_CT_PTHRU_CMD;
Daniel Wagner 1bf4db
 	sp->name = "gffid";
Daniel Wagner 1bf4db
 	sp->gen1 = fcport->rscn_gen;
Daniel Wagner 1bf4db
 	sp->gen2 = fcport->login_gen;
Daniel Wagner 1bf4db
 	qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
Daniel Wagner 1bf4db
 			      qla24xx_async_gffid_sp_done);
Daniel Wagner 1bf4db
+	sp->comp = ∁
Daniel Wagner 1bf4db
+	sp->u.iocb_cmd.timeout = qla2x00_els_dcmd2_iocb_timeout;
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+	if (wait)
Daniel Wagner 1bf4db
+		sp->flags = SRB_WAKEUP_ON_COMP;
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+	sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
Daniel Wagner 1bf4db
+	sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
Daniel Wagner 1bf4db
+				sp->u.iocb_cmd.u.ctarg.req_allocated_size,
Daniel Wagner 1bf4db
+				&sp->u.iocb_cmd.u.ctarg.req_dma,
Daniel Wagner 1bf4db
+	    GFP_KERNEL);
Daniel Wagner 1bf4db
+	if (!sp->u.iocb_cmd.u.ctarg.req) {
Daniel Wagner 1bf4db
+		ql_log(ql_log_warn, vha, 0xd041,
Daniel Wagner 1bf4db
+		       "%s: Failed to allocate ct_sns request.\n",
Daniel Wagner 1bf4db
+		       __func__);
Daniel Wagner 1bf4db
+		goto done_free_sp;
Daniel Wagner 1bf4db
+	}
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+	sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
Daniel Wagner 1bf4db
+	sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
Daniel Wagner 1bf4db
+				sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
Daniel Wagner 1bf4db
+				&sp->u.iocb_cmd.u.ctarg.rsp_dma,
Daniel Wagner 1bf4db
+	    GFP_KERNEL);
Daniel Wagner 1bf4db
+	if (!sp->u.iocb_cmd.u.ctarg.req) {
Daniel Wagner 1bf4db
+		ql_log(ql_log_warn, vha, 0xd041,
Daniel Wagner 1bf4db
+		       "%s: Failed to allocate ct_sns request.\n",
Daniel Wagner 1bf4db
+		       __func__);
Daniel Wagner 1bf4db
+		goto done_free_sp;
Daniel Wagner 1bf4db
+	}
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
 	/* CT_IU preamble  */
Daniel Wagner 1bf4db
-	ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD,
Daniel Wagner 1bf4db
-	    GFF_ID_RSP_SIZE);
Daniel Wagner 1bf4db
+	ct_req = qla2x00_prep_ct_req(sp->u.iocb_cmd.u.ctarg.req, GFF_ID_CMD, GFF_ID_RSP_SIZE);
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
 	ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
Daniel Wagner 1bf4db
 	ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
Daniel Wagner 1bf4db
 	ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-	sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
Daniel Wagner 1bf4db
-	sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
Daniel Wagner 1bf4db
-	sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
Daniel Wagner 1bf4db
-	sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
Daniel Wagner 1bf4db
 	sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE;
Daniel Wagner 1bf4db
 	sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
Daniel Wagner 1bf4db
 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-	ql_dbg(ql_dbg_disc, vha, 0x2132,
Daniel Wagner 1bf4db
-	    "Async-%s hdl=%x  %8phC.\n", sp->name,
Daniel Wagner 1bf4db
-	    sp->handle, fcport->port_name);
Daniel Wagner 1bf4db
-
Daniel Wagner 1bf4db
 	rval = qla2x00_start_sp(sp);
Daniel Wagner 1bf4db
-	if (rval != QLA_SUCCESS)
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+	if (rval != QLA_SUCCESS) {
Daniel Wagner 1bf4db
+		rval = QLA_FUNCTION_FAILED;
Daniel Wagner 1bf4db
 		goto done_free_sp;
Daniel Wagner 1bf4db
+	} else {
Daniel Wagner 1bf4db
+		ql_dbg(ql_dbg_disc, vha, 0x3074,
Daniel Wagner 1bf4db
+		       "Async-%s hdl=%x portid %06x\n",
Daniel Wagner 1bf4db
+		       sp->name, sp->handle, fcport->d_id.b24);
Daniel Wagner 1bf4db
+	}
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+	wait_for_completion(sp->comp);
Daniel Wagner 1bf4db
+	rval = sp->rc;
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-	return rval;
Daniel Wagner 1bf4db
 done_free_sp:
Daniel Wagner 1bf4db
+	if (sp->u.iocb_cmd.u.ctarg.req) {
Daniel Wagner 1bf4db
+		dma_free_coherent(&vha->hw->pdev->dev,
Daniel Wagner 1bf4db
+				  sp->u.iocb_cmd.u.ctarg.req_allocated_size,
Daniel Wagner 1bf4db
+				  sp->u.iocb_cmd.u.ctarg.req,
Daniel Wagner 1bf4db
+				  sp->u.iocb_cmd.u.ctarg.req_dma);
Daniel Wagner 1bf4db
+		sp->u.iocb_cmd.u.ctarg.req = NULL;
Daniel Wagner 1bf4db
+	}
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
+	if (sp->u.iocb_cmd.u.ctarg.rsp) {
Daniel Wagner 1bf4db
+		dma_free_coherent(&vha->hw->pdev->dev,
Daniel Wagner 1bf4db
+				  sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
Daniel Wagner 1bf4db
+				  sp->u.iocb_cmd.u.ctarg.rsp,
Daniel Wagner 1bf4db
+				  sp->u.iocb_cmd.u.ctarg.rsp_dma);
Daniel Wagner 1bf4db
+		sp->u.iocb_cmd.u.ctarg.rsp = NULL;
Daniel Wagner 1bf4db
+	}
Daniel Wagner 1bf4db
+
Daniel Wagner 1bf4db
 	/* ref: INIT */
Daniel Wagner 1bf4db
 	kref_put(&sp->cmd_kref, qla2x00_sp_release);
Daniel Wagner 1bf4db
-	fcport->flags &= ~FCF_ASYNC_SENT;
Daniel Wagner 1bf4db
 	return rval;
Daniel Wagner 1bf4db
 }
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
--- a/drivers/scsi/qla2xxx/qla_iocb.c
Daniel Wagner 1bf4db
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
Daniel Wagner 1bf4db
@@ -2822,7 +2822,7 @@ qla24xx_els_logo_iocb(srb_t *sp, struct
Daniel Wagner 1bf4db
 	sp->vha->qla_stats.control_requests++;
Daniel Wagner 1bf4db
 }
Daniel Wagner 1bf4db
 
Daniel Wagner 1bf4db
-static void
Daniel Wagner 1bf4db
+void
Daniel Wagner 1bf4db
 qla2x00_els_dcmd2_iocb_timeout(void *data)
Daniel Wagner 1bf4db
 {
Daniel Wagner 1bf4db
 	srb_t *sp = data;