diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index 9704cb13aacf..056fbdbc6794 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -342,6 +342,22 @@ extern uint ql_errlev;
 extern int ql2xnum_msg_trace;
 extern int ql2xextended_error_logging_msg_trace;
 
+#define QLA_SRB_TRACE_DEFINES \
+	int ql2xextended_error_logging_srb_trace = 1; \
+	module_param(ql2xextended_error_logging_srb_trace, int, \
+						S_IRUGO|S_IWUSR); \
+	MODULE_PARM_DESC(ql2xextended_error_logging_srb_trace, \
+		"Option to log srb messages to buffer; uses same " \
+			"ql2xextended_error_logging masks."); \
+	\
+	int ql2xnum_srb_trace = 0;	\
+	module_param(ql2xnum_srb_trace, int, S_IRUGO);	\
+	MODULE_PARM_DESC(ql2xnum_srb_trace, \
+		"Number of srb trace entries in power of 2. (default 0)");
+
+extern int ql2xnum_srb_trace;
+extern int ql2xextended_error_logging_srb_trace;
+
 extern struct qla_trace qla_message_trace;
 extern void qla_tracing_init(void);
 extern void qla_tracing_exit(void);
@@ -495,6 +511,57 @@ __ql_msg_trace(struct qla_trace *trc, scsi_qla_host_t *vha,
 	qla_trace_put(trc);
 }
 
+#define ql_srb_trace_ext(_level, _vha, _fcport, _fmt, _args...) do {	\
+	if (_fcport) {							\
+		__ql_srb_trace(_level, _vha,				\
+			DBG_FCPORT_PRFMT(_fcport, _fmt, ##_args));	\
+	} else {							\
+		__ql_srb_trace(_level, _vha,				\
+			"%s: " _fmt "\n", __func__, ##_args);		\
+	}								\
+} while (0)
+
+#define ql_srb_trace(_level, _vha, _fmt, _args...) \
+	__ql_srb_trace(_level, _vha, _fmt, ##_args)
+
+static inline void
+__ql_srb_trace(int level, scsi_qla_host_t *vha, const char *fmt, ...)
+{
+	int tl;
+	char *buf;
+	u64 t_us;
+	uint cpu;
+	struct va_format vaf;
+	va_list va;
+
+	if (!test_bit(QLA_TRACE_ENABLED, &vha->hw->srb_trace.flags))
+		return;
+
+	if (!ql_mask_match_ext(level, &ql2xextended_error_logging_srb_trace))
+		return;
+
+	t_us = ktime_to_us(ktime_get());
+	cpu = raw_smp_processor_id();
+	buf = qla_get_trace_next(&vha->hw->srb_trace);
+	if (!buf)
+		return;
+
+	va_start(va, fmt);
+
+	vaf.fmt = fmt;
+	vaf.va = &va;
+
+	tl = snprintf(buf, QLA_TRACE_LINE_SIZE, "%12llu %03u %pV",
+			t_us, cpu, &vaf);
+
+	tl = min(tl, QLA_TRACE_LINE_SIZE - 1);
+	buf[tl] = '\0';
+
+	qla_trace_put(&vha->hw->srb_trace);
+
+	va_end(va);
+}
+
 static inline void
 qla_trace_init(struct qla_trace *trc, char *name, u32 num_entries)
 {
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 39322105e7be..e1528a4e6ee4 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -4793,6 +4793,11 @@ struct qla_hw_data {
 	spinlock_t sadb_lock;	/* protects list */
 	struct els_reject elsrej;
 	u8 edif_post_stop_cnt_down;
+
+#ifdef QLA_TRACING
+	QLA_DFS_DEFINE_DENTRY(srb_trace);
+	struct qla_trace srb_trace;
+#endif /* QLA_TRACING */
 };
 
 #define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES))
@@ -5493,6 +5498,12 @@ struct ql_vnd_tgt_stats_resp {
 	struct ql_vnd_stats stats;
 } __packed;
 
+#define DBG_FCPORT_PRFMT(_fp, _fmt, _args...) \
+	"%s: %8phC: " _fmt " (state=%d disc_state=%d scan_state=%d loopid=0x%x deleted=%d flags=0x%x)\n", \
+	__func__, _fp->port_name, ##_args, atomic_read(&_fp->state), \
+	_fp->disc_state, _fp->scan_state, _fp->loop_id, _fp->deleted, \
+	_fp->flags
+
 #include "qla_target.h"
 #include "qla_gbl.h"
 #include "qla_dbg.h"
@@ -5501,10 +5512,4 @@ struct ql_vnd_tgt_stats_resp {
 #define IS_SESSION_DELETED(_fcport) (_fcport->disc_state == DSC_DELETE_PEND || \
 				      _fcport->disc_state == DSC_DELETED)
 
-#define DBG_FCPORT_PRFMT(_fp, _fmt, _args...) \
-	"%s: %8phC: " _fmt " (state=%d disc_state=%d scan_state=%d loopid=0x%x deleted=%d flags=0x%x)\n", \
-	__func__, _fp->port_name, ##_args, atomic_read(&_fp->state), \
-	_fp->disc_state, _fp->scan_state, _fp->loop_id, _fp->deleted, \
-	_fp->flags
-
 #endif
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index d3f9f6af43f2..806cb4afcb30 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -599,12 +599,26 @@ qla_dfs_message_trace_show(struct seq_file *s, void *unused)
 {
 	return qla_dfs_trace_show(s, unused);
 }
+
 static ssize_t
 qla_dfs_message_trace_write(struct file *file, const char __user *buffer,
 	size_t count, loff_t *pos)
 {
 	return qla_dfs_trace_write(file, buffer, count, pos);
 }
+
+static int
+qla_dfs_srb_trace_show(struct seq_file *s, void *unused)
+{
+	return qla_dfs_trace_show(s, unused);
+}
+
+static ssize_t
+qla_dfs_srb_trace_write(struct file *file, const char __user *buffer,
+	size_t count, loff_t *pos)
+{
+	return qla_dfs_trace_write(file, buffer, count, pos);
+}
 #endif /* QLA_TRACING */
 
 /*
@@ -699,6 +713,7 @@ static const struct file_operations qla_dfs_##_name##_ops = {		\
 
 #ifdef QLA_TRACING
 QLA_DFS_SETUP_RW(message_trace, struct qla_trace *);
+QLA_DFS_SETUP_RW(srb_trace, struct qla_trace *);
 #endif /* QLA_TRACING */
 
 static int
@@ -811,6 +826,7 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
 #ifdef QLA_TRACING
 	QLA_DFS_ROOT_CREATE_FILE(message_trace, 0600, &qla_message_trace);
 
+	QLA_DFS_CREATE_FILE(ha, srb_trace, 0600, ha->dfs_dir, &ha->srb_trace);
 #endif /* QLA_TRACING */
 
 	if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) {
@@ -875,6 +891,7 @@ qla2x00_dfs_remove(scsi_qla_host_t *vha)
 #ifdef QLA_TRACING
 	QLA_DFS_ROOT_REMOVE_FILE(message_trace);
 
+	QLA_DFS_REMOVE_FILE(ha, srb_trace);
 #endif /* QLA_TRACING */
 
 	if (ha->dfs_dir) {
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index db17f7f410cd..19f334693a38 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -201,6 +201,10 @@ qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair,
 		return NULL;
 
 	sp = mempool_alloc(qpair->srb_mempool, flag);
+	/* Avoid trace for calls from qla2x00_get_sp */
+	if (vha->hw->base_qpair != qpair)
+		ql_srb_trace_ext(ql_dbg_io, vha, fcport,
+			"sp=%px", sp);
 	if (sp)
 		qla2xxx_init_sp(sp, vha, qpair, fcport);
 	else
@@ -214,6 +218,10 @@ void qla2xxx_rel_free_warning(srb_t *sp);
 static inline void
 qla2xxx_rel_qpair_sp(struct qla_qpair *qpair, srb_t *sp)
 {
+	/* Avoid trace for calls from qla2x00_get_sp */
+	if (qpair->vha->hw->base_qpair != qpair)
+		ql_srb_trace_ext(ql_dbg_io, sp->vha, sp->fcport,
+			"sp=%px type=%d", sp, sp->type);
 	sp->qpair = NULL;
 	sp->done = qla2xxx_rel_done_warning;
 	sp->free = qla2xxx_rel_free_warning;
@@ -234,6 +242,7 @@ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
 
 	qpair = vha->hw->base_qpair;
 	sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, flag);
+	ql_srb_trace_ext(ql_dbg_disc, vha, fcport, "sp=%px", sp);
 	if (!sp)
 		goto done;
 
@@ -247,6 +256,9 @@ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
 static inline void
 qla2x00_rel_sp(srb_t *sp)
 {
+	ql_srb_trace_ext(ql_dbg_disc, sp->vha, sp->fcport,
+		"sp=%px type=%d", sp, sp->type);
+
 	QLA_VHA_MARK_NOT_BUSY(sp->vha);
 	qla2xxx_rel_qpair_sp(sp->qpair, sp);
 }
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 42ce4e1fe744..4fe569ef27ae 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -3826,6 +3826,10 @@ qla2x00_start_sp(srb_t *sp)
 	if (vha->hw->flags.eeh_busy)
 		return -EIO;
 
+	ql_srb_trace_ext(ql_dbg_disc, vha, sp->fcport,
+			"caller=%ps sp=%px type=%d",
+			__builtin_return_address(0), sp, sp->type);
+
 	spin_lock_irqsave(qp->qp_lock_ptr, flags);
 	pkt = __qla2x00_alloc_iocbs(sp->qpair, sp);
 	if (!pkt) {
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 76e79f350a22..af368d3beeab 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -3197,6 +3197,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 		}
 		return;
 	}
+
+	ql_srb_trace_ext(ql_dbg_io, vha, sp->fcport,
+			 "sp=%px handle=0x%x type=%d done=%ps",
+			 sp, sp->handle, sp->type, sp->done);
+
 	qla_put_iocbs(sp->qpair, &sp->iores);
 
 	if (sp->cmd_type != TYPE_SRB) {
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index b937283f5e53..4f9d2c1680c1 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -119,6 +119,8 @@ MODULE_PARM_DESC(ql2xextended_error_logging,
 
 QLA_MESSAGE_TRACE_DEFINES;
 
+QLA_SRB_TRACE_DEFINES;
+
 int ql2xshiftctondsd = 6;
 module_param(ql2xshiftctondsd, int, S_IRUGO);
 MODULE_PARM_DESC(ql2xshiftctondsd,
@@ -752,6 +754,10 @@ void qla2x00_sp_compl(srb_t *sp, int res)
 	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 	struct completion *comp = sp->comp;
 
+	ql_srb_trace_ext(ql_dbg_io, sp->vha, sp->fcport,
+			 "sp=%px handle=0x%x cmd=%px res=%x",
+			 sp, sp->handle, cmd, res);
+
 	/* kref: INIT */
 	kref_put(&sp->cmd_kref, qla2x00_sp_release);
 	cmd->result = res;
@@ -844,6 +850,10 @@ void qla2xxx_qpair_sp_compl(srb_t *sp, int res)
 	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 	struct completion *comp = sp->comp;
 
+	ql_srb_trace_ext(ql_dbg_io, sp->vha, sp->fcport,
+			 "sp=%px handle=0x%x cmd=%px res=%x",
+			 sp, sp->handle, cmd, res);
+
 	/* ref: INIT */
 	kref_put(&sp->cmd_kref, qla2x00_sp_release);
 	cmd->result = res;
@@ -870,6 +880,10 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 		goto qc24_fail_command;
 	}
 
+	ql_srb_trace_ext(ql_dbg_io, fcport->vha, fcport,
+		"cmd=%px mq=%d remchk=0x%x",
+		cmd, ha->mqenable, fc_remote_port_chkready(rport));
+
 	if (ha->mqenable) {
 		uint32_t tag;
 		uint16_t hwq;
@@ -877,6 +891,10 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 
 		tag = blk_mq_unique_tag(scsi_cmd_to_rq(cmd));
 		hwq = blk_mq_unique_tag_to_hwq(tag);
+
+		ql_srb_trace_ext(ql_dbg_io, fcport->vha, fcport,
+				 "tag=%px hwq=%d", tag, hwq);
+
 		qpair = ha->queue_pair_map[hwq];
 
 		if (qpair)
@@ -1298,6 +1316,10 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 
 	vha->cmd_timeout_cnt++;
 
+	ql_srb_trace_ext(ql_dbg_io, sp->vha, sp->fcport,
+			 "sp=%px cmd=%px fast_fail_sts=0x%x",
+			 sp, cmd, fast_fail_status);
+
 	if ((sp->fcport && sp->fcport->deleted) || !qpair)
 		return fast_fail_status != SUCCESS ? fast_fail_status : FAILED;
 
@@ -3528,6 +3550,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	ql_dbg(ql_dbg_init, base_vha, 0x00f2,
 	    "Init done and hba is online.\n");
 
+	qla_trace_init(&ha->srb_trace, "srb_trace", ql2xnum_srb_trace);
+
 	if (qla_ini_mode_enabled(base_vha) ||
 		qla_dual_mode_enabled(base_vha))
 		scsi_scan_host(host);
@@ -3600,6 +3624,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	rsp = NULL;
 
 probe_hw_failed:
+	qla_trace_uninit(&ha->srb_trace);
+
 	qla2x00_mem_free(ha);
 	qla2x00_free_req_que(ha, req);
 	qla2x00_free_rsp_que(ha, rsp);
@@ -3883,6 +3909,8 @@ qla2x00_remove_one(struct pci_dev *pdev)
 
 	qla2x00_delete_all_vps(ha, base_vha);
 
+	qla_trace_uninit(&ha->srb_trace);
+
 	qla2x00_dfs_remove(base_vha);
 
 	qla84xx_put_chip(base_vha);
