Blame SOURCES/0025-scsi-scsi-qla2xxx-Add-new-FW-dump-template-entry-typ.patch

3c6e85
From b26fc945948771916f20ca655dab101d2638d9c1 Mon Sep 17 00:00:00 2001
3c6e85
From: Himanshu Madhani <hmadhani@redhat.com>
3c6e85
Date: Thu, 1 Aug 2019 15:54:45 -0400
3c6e85
Subject: [PATCH 025/124] [scsi] scsi: qla2xxx: Add new FW dump template entry
3c6e85
 types
3c6e85
3c6e85
Message-id: <20190801155618.12650-26-hmadhani@redhat.com>
3c6e85
Patchwork-id: 267799
3c6e85
O-Subject: [RHEL 7.8 e-stor PATCH 025/118] scsi: qla2xxx: Add new FW dump template entry types
3c6e85
Bugzilla: 1729270
3c6e85
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
3c6e85
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
3c6e85
3c6e85
From: Joe Carnuccio <joe.carnuccio@cavium.com>
3c6e85
3c6e85
Bugzilla 1729270
3c6e85
3c6e85
This patch adds new firmware dump template entries for ISP27XX firmware
3c6e85
dump.
3c6e85
3c6e85
Signed-off-by: Joe Carnuccio <joe.carnuccio@cavium.com>
3c6e85
Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
3c6e85
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
3c6e85
(cherry picked from commit 64f61d9944839b62dea0ab6b0cafb4fb36c1f3f4)
3c6e85
Signed-off-by: Himanshu Madhani <hmadhani@redhat.com>
3c6e85
Signed-off-by: Jan Stancek <jstancek@redhat.com>
3c6e85
---
3c6e85
 drivers/scsi/qla2xxx/qla_tmpl.c | 191 +++++++++++++++++++++++++---------------
3c6e85
 drivers/scsi/qla2xxx/qla_tmpl.h |  26 +++++-
3c6e85
 2 files changed, 142 insertions(+), 75 deletions(-)
3c6e85
3c6e85
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c
3c6e85
index 9923f08331d0..6a0e94da4598 100644
3c6e85
--- a/drivers/scsi/qla2xxx/qla_tmpl.c
3c6e85
+++ b/drivers/scsi/qla2xxx/qla_tmpl.c
3c6e85
@@ -221,7 +221,13 @@ qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void *buf)
3c6e85
 		ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY;
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static inline struct qla27xx_fwdt_entry *
3c6e85
+qla27xx_next_entry(struct qla27xx_fwdt_entry *ent)
3c6e85
+{
3c6e85
+	return (void *)ent + ent->hdr.size;
3c6e85
+}
3c6e85
+
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t0(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -229,10 +235,10 @@ qla27xx_fwdt_entry_t0(struct scsi_qla_host *vha,
3c6e85
 	    "%s: nop [%lx]\n", __func__, *len);
3c6e85
 	qla27xx_skip_entry(ent, buf);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t255(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -241,10 +247,10 @@ qla27xx_fwdt_entry_t255(struct scsi_qla_host *vha,
3c6e85
 	qla27xx_skip_entry(ent, buf);
3c6e85
 
3c6e85
 	/* terminate */
3c6e85
-	return true;
3c6e85
+	return NULL;
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t256(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -255,10 +261,10 @@ qla27xx_fwdt_entry_t256(struct scsi_qla_host *vha,
3c6e85
 	qla27xx_read_window(reg, ent->t256.base_addr, ent->t256.pci_offset,
3c6e85
 	    ent->t256.reg_count, ent->t256.reg_width, buf, len);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t257(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -269,10 +275,10 @@ qla27xx_fwdt_entry_t257(struct scsi_qla_host *vha,
3c6e85
 	qla27xx_write_reg(reg, IOBASE_ADDR, ent->t257.base_addr, buf);
3c6e85
 	qla27xx_write_reg(reg, ent->t257.pci_offset, ent->t257.write_data, buf);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t258(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -284,10 +290,10 @@ qla27xx_fwdt_entry_t258(struct scsi_qla_host *vha,
3c6e85
 	qla27xx_read_window(reg, ent->t258.base_addr, ent->t258.pci_offset,
3c6e85
 	    ent->t258.reg_count, ent->t258.reg_width, buf, len);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t259(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -299,10 +305,10 @@ qla27xx_fwdt_entry_t259(struct scsi_qla_host *vha,
3c6e85
 	qla27xx_write_reg(reg, ent->t259.banksel_offset, ent->t259.bank, buf);
3c6e85
 	qla27xx_write_reg(reg, ent->t259.pci_offset, ent->t259.write_data, buf);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -313,10 +319,10 @@ qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha,
3c6e85
 	qla27xx_insert32(ent->t260.pci_offset, buf, len);
3c6e85
 	qla27xx_read_reg(reg, ent->t260.pci_offset, buf, len);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -326,10 +332,10 @@ qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha,
3c6e85
 	    "%s: wrpci [%lx]\n", __func__, *len);
3c6e85
 	qla27xx_write_reg(reg, ent->t261.pci_offset, ent->t261.write_data, buf);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -362,6 +368,11 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
3c6e85
 			ent->t262.start_addr = start;
3c6e85
 			ent->t262.end_addr = end;
3c6e85
 		}
3c6e85
+	} else if (ent->t262.ram_area == T262_RAM_AREA_MISC) {
3c6e85
+		if (buf) {
3c6e85
+			ent->t262.start_addr = start;
3c6e85
+			ent->t262.end_addr = end;
3c6e85
+		}
3c6e85
 	} else {
3c6e85
 		ql_dbg(ql_dbg_misc, vha, 0xd022,
3c6e85
 		    "%s: unknown area %x\n", __func__, ent->t262.ram_area);
3c6e85
@@ -384,10 +395,10 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
3c6e85
 	}
3c6e85
 	*len += dwords * sizeof(uint32_t);
3c6e85
 done:
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -450,10 +461,10 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
3c6e85
 			qla27xx_skip_entry(ent, buf);
3c6e85
 	}
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t264(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -478,10 +489,10 @@ qla27xx_fwdt_entry_t264(struct scsi_qla_host *vha,
3c6e85
 		qla27xx_skip_entry(ent, buf);
3c6e85
 	}
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -492,10 +503,10 @@ qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha,
3c6e85
 	if (buf)
3c6e85
 		qla24xx_pause_risc(reg, vha->hw);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t266(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -504,10 +515,10 @@ qla27xx_fwdt_entry_t266(struct scsi_qla_host *vha,
3c6e85
 	if (buf)
3c6e85
 		qla24xx_soft_reset(vha->hw);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t267(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -517,10 +528,10 @@ qla27xx_fwdt_entry_t267(struct scsi_qla_host *vha,
3c6e85
 	    "%s: dis intr [%lx]\n", __func__, *len);
3c6e85
 	qla27xx_write_reg(reg, ent->t267.pci_offset, ent->t267.data, buf);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t268(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -587,10 +598,10 @@ qla27xx_fwdt_entry_t268(struct scsi_qla_host *vha,
3c6e85
 		break;
3c6e85
 	}
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t269(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -604,10 +615,10 @@ qla27xx_fwdt_entry_t269(struct scsi_qla_host *vha,
3c6e85
 	if (buf)
3c6e85
 		ent->t269.scratch_size = 5 * sizeof(uint32_t);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -625,10 +636,10 @@ qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha,
3c6e85
 		addr += sizeof(uint32_t);
3c6e85
 	}
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -642,10 +653,10 @@ qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha,
3c6e85
 	qla27xx_write_reg(reg, 0xc4, data, buf);
3c6e85
 	qla27xx_write_reg(reg, 0xc0, addr, buf);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t272(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -662,10 +673,10 @@ qla27xx_fwdt_entry_t272(struct scsi_qla_host *vha,
3c6e85
 	}
3c6e85
 	*len += dwords * sizeof(uint32_t);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -685,10 +696,10 @@ qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha,
3c6e85
 		addr += sizeof(uint32_t);
3c6e85
 	}
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -746,10 +757,10 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
3c6e85
 			qla27xx_skip_entry(ent, buf);
3c6e85
 	}
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_t275(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
@@ -763,7 +774,7 @@ qla27xx_fwdt_entry_t275(struct scsi_qla_host *vha,
3c6e85
 		qla27xx_skip_entry(ent, buf);
3c6e85
 		goto done;
3c6e85
 	}
3c6e85
-	if (offset + ent->t275.length > ent->hdr.entry_size) {
3c6e85
+	if (offset + ent->t275.length > ent->hdr.size) {
3c6e85
 		ql_dbg(ql_dbg_misc, vha, 0xd030,
3c6e85
 		    "%s: buffer overflow\n", __func__);
3c6e85
 		qla27xx_skip_entry(ent, buf);
3c6e85
@@ -772,30 +783,71 @@ qla27xx_fwdt_entry_t275(struct scsi_qla_host *vha,
3c6e85
 
3c6e85
 	qla27xx_insertbuf(ent->t275.buffer, ent->t275.length, buf, len);
3c6e85
 done:
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-static int
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
+qla27xx_fwdt_entry_t276(struct scsi_qla_host *vha,
3c6e85
+    struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
+{
3c6e85
+	uint type = vha->hw->pdev->device >> 4 & 0xf;
3c6e85
+	uint func = vha->hw->port_no & 0x3;
3c6e85
+
3c6e85
+	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd214,
3c6e85
+	    "%s: cond [%lx]\n", __func__, *len);
3c6e85
+
3c6e85
+	if (type != ent->t276.cond1 || func != ent->t276.cond2) {
3c6e85
+		ent = qla27xx_next_entry(ent);
3c6e85
+		qla27xx_skip_entry(ent, buf);
3c6e85
+	}
3c6e85
+
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
+}
3c6e85
+
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
+qla27xx_fwdt_entry_t277(struct scsi_qla_host *vha,
3c6e85
+    struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
+{
3c6e85
+	struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
3c6e85
+
3c6e85
+	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd215,
3c6e85
+	    "%s: rdpep [%lx]\n", __func__, *len);
3c6e85
+	qla27xx_insert32(ent->t277.wr_cmd_data, buf, len);
3c6e85
+	qla27xx_write_reg(reg, ent->t277.cmd_addr, ent->t277.wr_cmd_data, buf);
3c6e85
+	qla27xx_read_reg(reg, ent->t277.data_addr, buf, len);
3c6e85
+
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
+}
3c6e85
+
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
+qla27xx_fwdt_entry_t278(struct scsi_qla_host *vha,
3c6e85
+    struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
+{
3c6e85
+	struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
3c6e85
+
3c6e85
+	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd216,
3c6e85
+	    "%s: wrpep [%lx]\n", __func__, *len);
3c6e85
+	qla27xx_write_reg(reg, ent->t278.data_addr, ent->t278.wr_data, buf);
3c6e85
+	qla27xx_write_reg(reg, ent->t278.cmd_addr, ent->t278.wr_cmd_data, buf);
3c6e85
+
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
+}
3c6e85
+
3c6e85
+static struct qla27xx_fwdt_entry *
3c6e85
 qla27xx_fwdt_entry_other(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
3c6e85
 {
3c6e85
 	ql_dbg(ql_dbg_misc, vha, 0xd2ff,
3c6e85
-	    "%s: type %x [%lx]\n", __func__, ent->hdr.entry_type, *len);
3c6e85
+	    "%s: type %x [%lx]\n", __func__, ent->hdr.type, *len);
3c6e85
 	qla27xx_skip_entry(ent, buf);
3c6e85
 
3c6e85
-	return false;
3c6e85
+	return qla27xx_next_entry(ent);
3c6e85
 }
3c6e85
 
3c6e85
-struct qla27xx_fwdt_entry_call {
3c6e85
+static struct {
3c6e85
 	uint type;
3c6e85
-	int (*call)(
3c6e85
-	    struct scsi_qla_host *,
3c6e85
-	    struct qla27xx_fwdt_entry *,
3c6e85
-	    void *,
3c6e85
-	    ulong *);
3c6e85
-};
3c6e85
-
3c6e85
-static struct qla27xx_fwdt_entry_call ql27xx_fwdt_entry_call_list[] = {
3c6e85
+	typeof(qla27xx_fwdt_entry_other)(*call);
3c6e85
+} qla27xx_fwdt_entry_call[] = {
3c6e85
 	{ ENTRY_TYPE_NOP,		qla27xx_fwdt_entry_t0    },
3c6e85
 	{ ENTRY_TYPE_TMP_END,		qla27xx_fwdt_entry_t255  },
3c6e85
 	{ ENTRY_TYPE_RD_IOB_T1,		qla27xx_fwdt_entry_t256  },
3c6e85
@@ -818,13 +870,16 @@ static struct qla27xx_fwdt_entry_call ql27xx_fwdt_entry_call_list[] = {
3c6e85
 	{ ENTRY_TYPE_PCICFG,		qla27xx_fwdt_entry_t273  },
3c6e85
 	{ ENTRY_TYPE_GET_SHADOW,	qla27xx_fwdt_entry_t274  },
3c6e85
 	{ ENTRY_TYPE_WRITE_BUF,		qla27xx_fwdt_entry_t275  },
3c6e85
+	{ ENTRY_TYPE_CONDITIONAL,	qla27xx_fwdt_entry_t276  },
3c6e85
+	{ ENTRY_TYPE_RDPEPREG,		qla27xx_fwdt_entry_t277  },
3c6e85
+	{ ENTRY_TYPE_WRPEPREG,		qla27xx_fwdt_entry_t278  },
3c6e85
 	{ -1,				qla27xx_fwdt_entry_other }
3c6e85
 };
3c6e85
 
3c6e85
-static inline int (*qla27xx_find_entry(uint type))
3c6e85
-	(struct scsi_qla_host *, struct qla27xx_fwdt_entry *, void *, ulong *)
3c6e85
+static inline
3c6e85
+typeof(qla27xx_fwdt_entry_call->call)(qla27xx_find_entry(uint type))
3c6e85
 {
3c6e85
-	struct qla27xx_fwdt_entry_call *list = ql27xx_fwdt_entry_call_list;
3c6e85
+	typeof(*qla27xx_fwdt_entry_call) *list = qla27xx_fwdt_entry_call;
3c6e85
 
3c6e85
 	while (list->type < type)
3c6e85
 		list++;
3c6e85
@@ -834,14 +889,6 @@ static inline int (*qla27xx_find_entry(uint type))
3c6e85
 	return qla27xx_fwdt_entry_other;
3c6e85
 }
3c6e85
 
3c6e85
-static inline void *
3c6e85
-qla27xx_next_entry(void *p)
3c6e85
-{
3c6e85
-	struct qla27xx_fwdt_entry *ent = p;
3c6e85
-
3c6e85
-	return p + ent->hdr.entry_size;
3c6e85
-}
3c6e85
-
3c6e85
 static void
3c6e85
 qla27xx_walk_template(struct scsi_qla_host *vha,
3c6e85
 	struct qla27xx_fwdt_template *tmp, void *buf, ulong *len)
3c6e85
@@ -852,18 +899,16 @@ qla27xx_walk_template(struct scsi_qla_host *vha,
3c6e85
 	ql_dbg(ql_dbg_misc, vha, 0xd01a,
3c6e85
 	    "%s: entry count %lx\n", __func__, count);
3c6e85
 	while (count--) {
3c6e85
-		if (buf && *len >= vha->hw->fw_dump_len)
3c6e85
+		ent = qla27xx_find_entry(ent->hdr.type)(vha, ent, buf, len);
3c6e85
+		if (!ent)
3c6e85
 			break;
3c6e85
-		if (qla27xx_find_entry(ent->hdr.entry_type)(vha, ent, buf, len))
3c6e85
-			break;
3c6e85
-		ent = qla27xx_next_entry(ent);
3c6e85
 	}
3c6e85
 
3c6e85
 	if (count)
3c6e85
 		ql_dbg(ql_dbg_misc, vha, 0xd018,
3c6e85
 		    "%s: entry residual count (%lx)\n", __func__, count);
3c6e85
 
3c6e85
-	if (ent->hdr.entry_type != ENTRY_TYPE_TMP_END)
3c6e85
+	if (ent)
3c6e85
 		ql_dbg(ql_dbg_misc, vha, 0xd019,
3c6e85
 		    "%s: missing end entry (%lx)\n", __func__, count);
3c6e85
 
3c6e85
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.h b/drivers/scsi/qla2xxx/qla_tmpl.h
3c6e85
index da0f506a8b70..f7990f2a057a 100644
3c6e85
--- a/drivers/scsi/qla2xxx/qla_tmpl.h
3c6e85
+++ b/drivers/scsi/qla2xxx/qla_tmpl.h
3c6e85
@@ -54,6 +54,9 @@ struct __packed qla27xx_fwdt_template {
3c6e85
 #define ENTRY_TYPE_PCICFG		273
3c6e85
 #define ENTRY_TYPE_GET_SHADOW		274
3c6e85
 #define ENTRY_TYPE_WRITE_BUF		275
3c6e85
+#define ENTRY_TYPE_CONDITIONAL		276
3c6e85
+#define ENTRY_TYPE_RDPEPREG		277
3c6e85
+#define ENTRY_TYPE_WRPEPREG		278
3c6e85
 
3c6e85
 #define CAPTURE_FLAG_PHYS_ONLY		BIT_0
3c6e85
 #define CAPTURE_FLAG_PHYS_VIRT		BIT_1
3c6e85
@@ -62,8 +65,8 @@ struct __packed qla27xx_fwdt_template {
3c6e85
 
3c6e85
 struct __packed qla27xx_fwdt_entry {
3c6e85
 	struct __packed {
3c6e85
-		uint32_t entry_type;
3c6e85
-		uint32_t entry_size;
3c6e85
+		uint32_t type;
3c6e85
+		uint32_t size;
3c6e85
 		uint32_t reserved_1;
3c6e85
 
3c6e85
 		uint8_t  capture_flags;
3c6e85
@@ -199,6 +202,24 @@ struct __packed qla27xx_fwdt_entry {
3c6e85
 			uint32_t length;
3c6e85
 			uint8_t  buffer[];
3c6e85
 		} t275;
3c6e85
+
3c6e85
+		struct __packed {
3c6e85
+			uint32_t cond1;
3c6e85
+			uint32_t cond2;
3c6e85
+		} t276;
3c6e85
+
3c6e85
+		struct __packed {
3c6e85
+			uint32_t cmd_addr;
3c6e85
+			uint32_t wr_cmd_data;
3c6e85
+			uint32_t data_addr;
3c6e85
+		} t277;
3c6e85
+
3c6e85
+		struct __packed {
3c6e85
+			uint32_t cmd_addr;
3c6e85
+			uint32_t wr_cmd_data;
3c6e85
+			uint32_t data_addr;
3c6e85
+			uint32_t wr_data;
3c6e85
+		} t278;
3c6e85
 	};
3c6e85
 };
3c6e85
 
3c6e85
@@ -206,6 +227,7 @@ struct __packed qla27xx_fwdt_entry {
3c6e85
 #define T262_RAM_AREA_EXTERNAL_RAM	2
3c6e85
 #define T262_RAM_AREA_SHARED_RAM	3
3c6e85
 #define T262_RAM_AREA_DDR_RAM		4
3c6e85
+#define T262_RAM_AREA_MISC		5
3c6e85
 
3c6e85
 #define T263_QUEUE_TYPE_REQ		1
3c6e85
 #define T263_QUEUE_TYPE_RSP		2
3c6e85
-- 
3c6e85
2.13.6
3c6e85