/*
 * QLogic Fibre Channel HBA Driver
 * Copyright (c)  2003-2014 QLogic Corporation
 *
 * See LICENSE.qla2xxx for copyright and licensing details.
 */
#include "qla_def.h"
#include "qla_tmpl.h"

#define ISPREG(vha)	(&(vha)->hw->iobase->isp24)
#define IOBAR(reg)	offsetof(typeof(*(reg)), iobase_addr)
#define IOBASE(vha)	IOBAR(ISPREG(vha))

static inline void
qla27xx_insert16(uint16_t value, void *buf, ulong *len)
{
	if (buf) {
		buf += *len;
		*(__le16 *)buf = cpu_to_le16(value);
	}
	*len += sizeof(value);
}

static inline void
qla27xx_insert32(uint32_t value, void *buf, ulong *len)
{
	if (buf) {
		buf += *len;
		*(__le32 *)buf = cpu_to_le32(value);
	}
	*len += sizeof(value);
}

static inline void
qla27xx_insertbuf(void *mem, ulong size, void *buf, ulong *len)
{
	if (buf && mem && size) {
		buf += *len;
		memcpy(buf, mem, size);
	}
	*len += size;
}

static inline void
qla27xx_read8(void __iomem *window, void *buf, ulong *len)
{
	uint8_t value = ~0;

	if (buf) {
		value = RD_REG_BYTE(window);
	}
	qla27xx_insert32(value, buf, len);
}

static inline void
qla27xx_read16(void __iomem *window, void *buf, ulong *len)
{
	uint16_t value = ~0;

	if (buf) {
		value = RD_REG_WORD(window);
	}
	qla27xx_insert32(value, buf, len);
}

static inline void
qla27xx_read32(void __iomem *window, void *buf, ulong *len)
{
	uint32_t value = ~0;

	if (buf) {
		value = RD_REG_DWORD(window);
	}
	qla27xx_insert32(value, buf, len);
}

static inline void (*qla27xx_read_vector(uint width))(void __iomem*, void *, ulong *)
{
	return
	    (width == 1) ? qla27xx_read8 :
	    (width == 2) ? qla27xx_read16 :
			   qla27xx_read32;
}

static inline void
qla27xx_read_reg(__iomem struct device_reg_24xx *reg,
	uint offset, void *buf, ulong *len)
{
	void __iomem *window = (void __iomem *)reg + offset;

	qla27xx_read32(window, buf, len);
}

static inline void
qla27xx_write_reg(__iomem struct device_reg_24xx *reg,
	uint offset, uint32_t data, void *buf)
{
	if (buf) {
		void __iomem *window = (void __iomem *)reg + offset;

		WRT_REG_DWORD(window, data);
	}
}

static inline void
qla27xx_read_window(__iomem struct device_reg_24xx *reg,
	uint32_t addr, uint offset, uint count, uint width, void *buf,
	ulong *len)
{
	void __iomem *window = (void __iomem *)reg + offset;
	void (*readn)(void __iomem*, void *, ulong *) = qla27xx_read_vector(width);

	qla27xx_write_reg(reg, IOBAR(reg), addr, buf);
	while (count--) {
		qla27xx_insert32(addr, buf, len);
		readn(window, buf, len);
		window += width;
		addr++;
	}
}

static inline void
qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void *buf)
{
	if (buf)
		ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY;
}

static inline struct qla27xx_fwdt_entry *
qla27xx_next_entry(struct qla27xx_fwdt_entry *ent)
{
	return (void *)ent + le32_to_cpu(ent->hdr.size);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t0(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ql_dbg(ql_dbg_misc, vha, 0xd100,
	    "%s: nop [%lx]\n", __func__, *len);
	qla27xx_skip_entry(ent, buf);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t255(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ql_dbg(ql_dbg_misc, vha, 0xd1ff,
	    "%s: end [%lx]\n", __func__, *len);
	qla27xx_skip_entry(ent, buf);

	/* terminate */
	return NULL;
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t256(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong addr = le32_to_cpu(ent->t256.base_addr);
	uint offset = ent->t256.pci_offset;
	ulong count = le16_to_cpu(ent->t256.reg_count);
	uint width = ent->t256.reg_width;

	ql_dbg(ql_dbg_misc, vha, 0xd200,
	    "%s: rdio t1 [%lx]\n", __func__, *len);
	qla27xx_read_window(ISPREG(vha), addr, offset, count, width, buf, len);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t257(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong addr = le32_to_cpu(ent->t257.base_addr);
	uint offset = ent->t257.pci_offset;
	ulong data = le32_to_cpu(ent->t257.write_data);

	ql_dbg(ql_dbg_misc, vha, 0xd201,
	    "%s: wrio t1 [%lx]\n", __func__, *len);
	qla27xx_write_reg(ISPREG(vha), IOBASE(vha), addr, buf);
	qla27xx_write_reg(ISPREG(vha), offset, data, buf);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t258(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	uint banksel = ent->t258.banksel_offset;
	ulong bank = le32_to_cpu(ent->t258.bank);
	ulong addr = le32_to_cpu(ent->t258.base_addr);
	uint offset = ent->t258.pci_offset;
	uint count = le16_to_cpu(ent->t258.reg_count);
	uint width = ent->t258.reg_width;

	ql_dbg(ql_dbg_misc, vha, 0xd202,
	    "%s: rdio t2 [%lx]\n", __func__, *len);
	qla27xx_write_reg(ISPREG(vha), banksel, bank, buf);
	qla27xx_read_window(ISPREG(vha), addr, offset, count, width, buf, len);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t259(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong addr = le32_to_cpu(ent->t259.base_addr);
	uint banksel = ent->t259.banksel_offset;
	ulong bank = le32_to_cpu(ent->t259.bank);
	uint offset = ent->t259.pci_offset;
	ulong data = le32_to_cpu(ent->t259.write_data);

	ql_dbg(ql_dbg_misc, vha, 0xd203,
	    "%s: wrio t2 [%lx]\n", __func__, *len);
	qla27xx_write_reg(ISPREG(vha), IOBASE(vha), addr, buf);
	qla27xx_write_reg(ISPREG(vha), banksel, bank, buf);
	qla27xx_write_reg(ISPREG(vha), offset, data, buf);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	uint offset = ent->t260.pci_offset;

	ql_dbg(ql_dbg_misc, vha, 0xd204,
	    "%s: rdpci [%lx]\n", __func__, *len);
	qla27xx_insert32(offset, buf, len);
	qla27xx_read_reg(ISPREG(vha), offset, buf, len);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	uint offset = ent->t261.pci_offset;
	ulong data = le32_to_cpu(ent->t261.write_data);

	ql_dbg(ql_dbg_misc, vha, 0xd205,
	    "%s: wrpci [%lx]\n", __func__, *len);
	qla27xx_write_reg(ISPREG(vha), offset, data, buf);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	uint area = ent->t262.ram_area;
	ulong start = le32_to_cpu(ent->t262.start_addr);
	ulong end = le32_to_cpu(ent->t262.end_addr);
	ulong dwords;

	ql_dbg(ql_dbg_misc, vha, 0xd206,
	    "%s: rdram(%x) [%lx]\n", __func__, ent->t262.ram_area, *len);

	if (area == T262_RAM_AREA_CRITICAL_RAM) {
		;
	} else if (area == T262_RAM_AREA_EXTERNAL_RAM) {
		end = vha->hw->fw_memory_size;
		if (buf)
			ent->t262.end_addr = cpu_to_le32(end);
	} else if (area == T262_RAM_AREA_SHARED_RAM) {
		start = vha->hw->fw_shared_ram_start;
		end = vha->hw->fw_shared_ram_end;
		if (buf) {
			ent->t262.start_addr = cpu_to_le32(start);
			ent->t262.end_addr = cpu_to_le32(end);
		}
	} else if (area == T262_RAM_AREA_DDR_RAM) {
		start = vha->hw->fw_ddr_ram_start;
		end = vha->hw->fw_ddr_ram_end;
		if (buf) {
			ent->t262.start_addr = cpu_to_le32(start);
			ent->t262.end_addr = cpu_to_le32(end);
		}
	} else if (area == T262_RAM_AREA_MISC) {
		if (buf) {
			ent->t262.start_addr = cpu_to_le32(start);
			ent->t262.end_addr = cpu_to_le32(end);
		}
	} else {
		ql_dbg(ql_dbg_misc, vha, 0xd022,
		    "%s: unknown area %x\n", __func__, area);
		qla27xx_skip_entry(ent, buf);
		goto done;
	}

	if (end < start || start == 0 || end == 0) {
		ql_dbg(ql_dbg_misc, vha, 0xd023,
		    "%s: unusable range (start=%lx end=%lx)\n",
		    __func__, start, end);
		qla27xx_skip_entry(ent, buf);
		goto done;
	}

	dwords = end - start + 1;
	if (buf) {
		buf += *len;
		qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf);
	}
	*len += dwords * sizeof(uint32_t);
done:
	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	uint type = ent->t263.queue_type;
	uint count = 0;
	uint i;
	uint length;

	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd207,
	    "%s: getq(%x) [%lx]\n", __func__, type, *len);
	if (type == T263_QUEUE_TYPE_REQ) {
		for (i = 0; i < vha->hw->max_req_queues; i++) {
			struct req_que *req = vha->hw->req_q_map[i];

			if (req || !buf) {
				length = req ?
				    req->length : REQUEST_ENTRY_CNT_24XX;
				qla27xx_insert16(i, buf, len);
				qla27xx_insert16(length, buf, len);
				qla27xx_insertbuf(req ? req->ring : NULL,
				    length * sizeof(*req->ring), buf, len);
				count++;
			}
		}
	} else if (type == T263_QUEUE_TYPE_RSP) {
		for (i = 0; i < vha->hw->max_rsp_queues; i++) {
			struct rsp_que *rsp = vha->hw->rsp_q_map[i];

			if (rsp || !buf) {
				length = rsp ?
				    rsp->length : RESPONSE_ENTRY_CNT_MQ;
				qla27xx_insert16(i, buf, len);
				qla27xx_insert16(length, buf, len);
				qla27xx_insertbuf(rsp ? rsp->ring : NULL,
				    length * sizeof(*rsp->ring), buf, len);
				count++;
			}
		}
	} else if (QLA_TGT_MODE_ENABLED() &&
	    ent->t263.queue_type == T263_QUEUE_TYPE_ATIO) {
		struct qla_hw_data *ha = vha->hw;
		struct atio *atr = ha->tgt.atio_ring;

		if (atr || !buf) {
			length = ha->tgt.atio_q_length;
			qla27xx_insert16(0, buf, len);
			qla27xx_insert16(length, buf, len);
			qla27xx_insertbuf(atr, length * sizeof(*atr), buf, len);
			count++;
		}
	} else {
		ql_dbg(ql_dbg_misc, vha, 0xd026,
		    "%s: unknown queue %x\n", __func__, type);
		qla27xx_skip_entry(ent, buf);
	}

	if (buf) {
		if (count)
			ent->t263.num_queues = count;
		else
			qla27xx_skip_entry(ent, buf);
	}

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t264(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ql_dbg(ql_dbg_misc, vha, 0xd208,
	    "%s: getfce [%lx]\n", __func__, *len);
	if (vha->hw->fce) {
		if (buf) {
			ent->t264.fce_trace_size = FCE_SIZE;
			ent->t264.write_pointer = vha->hw->fce_wr;
			ent->t264.base_pointer = vha->hw->fce_dma;
			ent->t264.fce_enable_mb0 = vha->hw->fce_mb[0];
			ent->t264.fce_enable_mb2 = vha->hw->fce_mb[2];
			ent->t264.fce_enable_mb3 = vha->hw->fce_mb[3];
			ent->t264.fce_enable_mb4 = vha->hw->fce_mb[4];
			ent->t264.fce_enable_mb5 = vha->hw->fce_mb[5];
			ent->t264.fce_enable_mb6 = vha->hw->fce_mb[6];
		}
		qla27xx_insertbuf(vha->hw->fce, FCE_SIZE, buf, len);
	} else {
		ql_dbg(ql_dbg_misc, vha, 0xd027,
		    "%s: missing fce\n", __func__);
		qla27xx_skip_entry(ent, buf);
	}

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd209,
	    "%s: pause risc [%lx]\n", __func__, *len);
	if (buf)
		qla24xx_pause_risc(ISPREG(vha), vha->hw);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t266(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ql_dbg(ql_dbg_misc, vha, 0xd20a,
	    "%s: reset risc [%lx]\n", __func__, *len);
	if (buf)
		qla24xx_soft_reset(vha->hw);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t267(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	uint offset = ent->t267.pci_offset;
	ulong data = le32_to_cpu(ent->t267.data);

	ql_dbg(ql_dbg_misc, vha, 0xd20b,
	    "%s: dis intr [%lx]\n", __func__, *len);
	qla27xx_write_reg(ISPREG(vha), offset, data, buf);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t268(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ql_dbg(ql_dbg_misc, vha, 0xd20c,
	    "%s: gethb(%x) [%lx]\n", __func__, ent->t268.buf_type, *len);
	switch (ent->t268.buf_type) {
	case T268_BUF_TYPE_EXTD_TRACE:
		if (vha->hw->eft) {
			if (buf) {
				ent->t268.buf_size = EFT_SIZE;
				ent->t268.start_addr = vha->hw->eft_dma;
			}
			qla27xx_insertbuf(vha->hw->eft, EFT_SIZE, buf, len);
		} else {
			ql_dbg(ql_dbg_misc, vha, 0xd028,
			    "%s: missing eft\n", __func__);
			qla27xx_skip_entry(ent, buf);
		}
		break;
	case T268_BUF_TYPE_EXCH_BUFOFF:
		if (vha->hw->exchoffld_buf) {
			if (buf) {
				ent->t268.buf_size = vha->hw->exchoffld_size;
				ent->t268.start_addr =
					vha->hw->exchoffld_buf_dma;
			}
			qla27xx_insertbuf(vha->hw->exchoffld_buf,
			    vha->hw->exchoffld_size, buf, len);
		} else {
			ql_dbg(ql_dbg_misc, vha, 0xd028,
			    "%s: missing exch offld\n", __func__);
			qla27xx_skip_entry(ent, buf);
		}
		break;
	case T268_BUF_TYPE_EXTD_LOGIN:
		if (vha->hw->exlogin_buf) {
			if (buf) {
				ent->t268.buf_size = vha->hw->exlogin_size;
				ent->t268.start_addr =
					vha->hw->exlogin_buf_dma;
			}
			qla27xx_insertbuf(vha->hw->exlogin_buf,
			    vha->hw->exlogin_size, buf, len);
		} else {
			ql_dbg(ql_dbg_misc, vha, 0xd028,
			    "%s: missing ext login\n", __func__);
			qla27xx_skip_entry(ent, buf);
		}
		break;

	case T268_BUF_TYPE_REQ_MIRROR:
	case T268_BUF_TYPE_RSP_MIRROR:
		/*
		 * Mirror pointers are not implemented in the
		 * driver, instead shadow pointers are used by
		 * the drier. Skip these entries.
		 */
		qla27xx_skip_entry(ent, buf);
		break;
	default:
		ql_dbg(ql_dbg_async, vha, 0xd02b,
		    "%s: unknown buffer %x\n", __func__, ent->t268.buf_type);
		qla27xx_skip_entry(ent, buf);
		break;
	}

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t269(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ql_dbg(ql_dbg_misc, vha, 0xd20d,
	    "%s: scratch [%lx]\n", __func__, *len);
	qla27xx_insert32(0xaaaaaaaa, buf, len);
	qla27xx_insert32(0xbbbbbbbb, buf, len);
	qla27xx_insert32(0xcccccccc, buf, len);
	qla27xx_insert32(0xdddddddd, buf, len);
	qla27xx_insert32(*len + sizeof(uint32_t), buf, len);
	if (buf)
		ent->t269.scratch_size = 5 * sizeof(uint32_t);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong addr = le32_to_cpu(ent->t270.addr);
	ulong dwords = le32_to_cpu(ent->t270.count);

	ql_dbg(ql_dbg_misc, vha, 0xd20e,
	    "%s: rdremreg [%lx]\n", __func__, *len);
	qla27xx_write_reg(ISPREG(vha), IOBASE_ADDR, 0x40, buf);
	while (dwords--) {
		qla27xx_write_reg(ISPREG(vha), 0xc0, addr|0x80000000, buf);
		qla27xx_insert32(addr, buf, len);
		qla27xx_read_reg(ISPREG(vha), 0xc4, buf, len);
		addr += sizeof(uint32_t);
	}

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong addr = le32_to_cpu(ent->t271.addr);
	ulong data = le32_to_cpu(ent->t271.data);

	ql_dbg(ql_dbg_misc, vha, 0xd20f,
	    "%s: wrremreg [%lx]\n", __func__, *len);
	qla27xx_write_reg(ISPREG(vha), IOBASE(vha), 0x40, buf);
	qla27xx_write_reg(ISPREG(vha), 0xc4, data, buf);
	qla27xx_write_reg(ISPREG(vha), 0xc0, addr, buf);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t272(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong dwords = le32_to_cpu(ent->t272.count);
	ulong start = le32_to_cpu(ent->t272.addr);

	ql_dbg(ql_dbg_misc, vha, 0xd210,
	    "%s: rdremram [%lx]\n", __func__, *len);
	if (buf) {
		ql_dbg(ql_dbg_misc, vha, 0xd02c,
		    "%s: @%lx -> (%lx dwords)\n", __func__, start, dwords);
		buf += *len;
		qla27xx_dump_mpi_ram(vha->hw, start, buf, dwords, &buf);
	}
	*len += dwords * sizeof(uint32_t);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong dwords = le32_to_cpu(ent->t273.count);
	ulong addr = le32_to_cpu(ent->t273.addr);
	uint32_t value;

	ql_dbg(ql_dbg_misc, vha, 0xd211,
	    "%s: pcicfg [%lx]\n", __func__, *len);
	while (dwords--) {
		value = ~0;
		if (pci_read_config_dword(vha->hw->pdev, addr, &value))
			ql_dbg(ql_dbg_misc, vha, 0xd02d,
			    "%s: failed pcicfg read at %lx\n", __func__, addr);
		qla27xx_insert32(addr, buf, len);
		qla27xx_insert32(value, buf, len);
		addr += sizeof(uint32_t);
	}

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong type = ent->t274.queue_type;
	uint count = 0;
	uint i;

	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd212,
	    "%s: getqsh(%lx) [%lx]\n", __func__, type, *len);
	if (type == T274_QUEUE_TYPE_REQ_SHAD) {
		for (i = 0; i < vha->hw->max_req_queues; i++) {
			struct req_que *req = vha->hw->req_q_map[i];

			if (req || !buf) {
				qla27xx_insert16(i, buf, len);
				qla27xx_insert16(1, buf, len);
				qla27xx_insert32(req && req->out_ptr ?
				    *req->out_ptr : 0, buf, len);
				count++;
			}
		}
	} else if (type == T274_QUEUE_TYPE_RSP_SHAD) {
		for (i = 0; i < vha->hw->max_rsp_queues; i++) {
			struct rsp_que *rsp = vha->hw->rsp_q_map[i];

			if (rsp || !buf) {
				qla27xx_insert16(i, buf, len);
				qla27xx_insert16(1, buf, len);
				qla27xx_insert32(rsp && rsp->in_ptr ?
				    *rsp->in_ptr : 0, buf, len);
				count++;
			}
		}
	} else if (QLA_TGT_MODE_ENABLED() &&
	    ent->t274.queue_type == T274_QUEUE_TYPE_ATIO_SHAD) {
		struct qla_hw_data *ha = vha->hw;
		struct atio *atr = ha->tgt.atio_ring_ptr;

		if (atr || !buf) {
			qla27xx_insert16(0, buf, len);
			qla27xx_insert16(1, buf, len);
			qla27xx_insert32(ha->tgt.atio_q_in ?
			    readl(ha->tgt.atio_q_in) : 0, buf, len);
			count++;
		}
	} else {
		ql_dbg(ql_dbg_misc, vha, 0xd02f,
		    "%s: unknown queue %lx\n", __func__, type);
		qla27xx_skip_entry(ent, buf);
	}

	if (buf) {
		if (count)
			ent->t274.num_queues = count;
		else
			qla27xx_skip_entry(ent, buf);
	}

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t275(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong offset = offsetof(typeof(*ent), t275.buffer);
	ulong length = le32_to_cpu(ent->t275.length);
	ulong size = le32_to_cpu(ent->hdr.size);
	void *buffer = ent->t275.buffer;

	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd213,
	    "%s: buffer(%lx) [%lx]\n", __func__, length, *len);
	if (!length) {
		ql_dbg(ql_dbg_misc, vha, 0xd020,
		    "%s: buffer zero length\n", __func__);
		qla27xx_skip_entry(ent, buf);
		goto done;
	}
	if (offset + length > size) {
		length = size - offset;
		ql_dbg(ql_dbg_misc, vha, 0xd030,
		    "%s: buffer overflow, truncate [%lx]\n", __func__, length);
		ent->t275.length = cpu_to_le32(length);
	}

	qla27xx_insertbuf(buffer, length, buf, len);
done:
	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t276(struct scsi_qla_host *vha,
    struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd214,
	    "%s: cond [%lx]\n", __func__, *len);

	if (buf) {
		ulong cond1 = le32_to_cpu(ent->t276.cond1);
		ulong cond2 = le32_to_cpu(ent->t276.cond2);
		uint type = vha->hw->pdev->device >> 4 & 0xf;
		uint func = vha->hw->port_no & 0x3;

		if (type != cond1 || func != cond2) {
			struct qla27xx_fwdt_template *tmp = buf;

			tmp->count--;
			ent = qla27xx_next_entry(ent);
			qla27xx_skip_entry(ent, buf);
		}
	}

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t277(struct scsi_qla_host *vha,
    struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong cmd_addr = le32_to_cpu(ent->t277.cmd_addr);
	ulong wr_cmd_data = le32_to_cpu(ent->t277.wr_cmd_data);
	ulong data_addr = le32_to_cpu(ent->t277.data_addr);

	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd215,
	    "%s: rdpep [%lx]\n", __func__, *len);
	qla27xx_insert32(wr_cmd_data, buf, len);
	qla27xx_write_reg(ISPREG(vha), cmd_addr, wr_cmd_data, buf);
	qla27xx_read_reg(ISPREG(vha), data_addr, buf, len);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_t278(struct scsi_qla_host *vha,
    struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong cmd_addr = le32_to_cpu(ent->t278.cmd_addr);
	ulong wr_cmd_data = le32_to_cpu(ent->t278.wr_cmd_data);
	ulong data_addr = le32_to_cpu(ent->t278.data_addr);
	ulong wr_data = le32_to_cpu(ent->t278.wr_data);

	ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd216,
	    "%s: wrpep [%lx]\n", __func__, *len);
	qla27xx_write_reg(ISPREG(vha), data_addr, wr_data, buf);
	qla27xx_write_reg(ISPREG(vha), cmd_addr, wr_cmd_data, buf);

	return qla27xx_next_entry(ent);
}

static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_other(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
	ulong type = le32_to_cpu(ent->hdr.type);

	ql_dbg(ql_dbg_misc, vha, 0xd2ff,
	    "%s: other %lx [%lx]\n", __func__, type, *len);
	qla27xx_skip_entry(ent, buf);

	return qla27xx_next_entry(ent);
}

static struct {
	uint type;
	typeof(qla27xx_fwdt_entry_other)(*call);
} qla27xx_fwdt_entry_call[] = {
	{ ENTRY_TYPE_NOP,		qla27xx_fwdt_entry_t0    },
	{ ENTRY_TYPE_TMP_END,		qla27xx_fwdt_entry_t255  },
	{ ENTRY_TYPE_RD_IOB_T1,		qla27xx_fwdt_entry_t256  },
	{ ENTRY_TYPE_WR_IOB_T1,		qla27xx_fwdt_entry_t257  },
	{ ENTRY_TYPE_RD_IOB_T2,		qla27xx_fwdt_entry_t258  },
	{ ENTRY_TYPE_WR_IOB_T2,		qla27xx_fwdt_entry_t259  },
	{ ENTRY_TYPE_RD_PCI,		qla27xx_fwdt_entry_t260  },
	{ ENTRY_TYPE_WR_PCI,		qla27xx_fwdt_entry_t261  },
	{ ENTRY_TYPE_RD_RAM,		qla27xx_fwdt_entry_t262  },
	{ ENTRY_TYPE_GET_QUEUE,		qla27xx_fwdt_entry_t263  },
	{ ENTRY_TYPE_GET_FCE,		qla27xx_fwdt_entry_t264  },
	{ ENTRY_TYPE_PSE_RISC,		qla27xx_fwdt_entry_t265  },
	{ ENTRY_TYPE_RST_RISC,		qla27xx_fwdt_entry_t266  },
	{ ENTRY_TYPE_DIS_INTR,		qla27xx_fwdt_entry_t267  },
	{ ENTRY_TYPE_GET_HBUF,		qla27xx_fwdt_entry_t268  },
	{ ENTRY_TYPE_SCRATCH,		qla27xx_fwdt_entry_t269  },
	{ ENTRY_TYPE_RDREMREG,		qla27xx_fwdt_entry_t270  },
	{ ENTRY_TYPE_WRREMREG,		qla27xx_fwdt_entry_t271  },
	{ ENTRY_TYPE_RDREMRAM,		qla27xx_fwdt_entry_t272  },
	{ ENTRY_TYPE_PCICFG,		qla27xx_fwdt_entry_t273  },
	{ ENTRY_TYPE_GET_SHADOW,	qla27xx_fwdt_entry_t274  },
	{ ENTRY_TYPE_WRITE_BUF,		qla27xx_fwdt_entry_t275  },
	{ ENTRY_TYPE_CONDITIONAL,	qla27xx_fwdt_entry_t276  },
	{ ENTRY_TYPE_RDPEPREG,		qla27xx_fwdt_entry_t277  },
	{ ENTRY_TYPE_WRPEPREG,		qla27xx_fwdt_entry_t278  },
	{ -1,				qla27xx_fwdt_entry_other }
};

static inline
typeof(qla27xx_fwdt_entry_call->call)(qla27xx_find_entry(uint type))
{
	typeof(*qla27xx_fwdt_entry_call) *list = qla27xx_fwdt_entry_call;

	while (list->type < type)
		list++;

	if (list->type == type)
		return list->call;
	return qla27xx_fwdt_entry_other;
}

static void
qla27xx_walk_template(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_template *tmp, void *buf, ulong *len)
{
	struct qla27xx_fwdt_entry *ent = (void *)tmp +
	    le32_to_cpu(tmp->entry_offset);
	ulong type;

	tmp->count = le32_to_cpu(tmp->entry_count);
	ql_dbg(ql_dbg_misc, vha, 0xd01a,
	    "%s: entry count %u\n", __func__, tmp->count);
	while (ent && tmp->count--) {
		type = le32_to_cpu(ent->hdr.type);
		ent = qla27xx_find_entry(type)(vha, ent, buf, len);
		if (!ent)
			break;
	}

	if (tmp->count)
		ql_dbg(ql_dbg_misc, vha, 0xd018,
		    "%s: entry count residual=+%u\n", __func__, tmp->count);

	if (ent)
		ql_dbg(ql_dbg_misc, vha, 0xd019,
		    "%s: missing end entry\n", __func__);
}

static void
qla27xx_time_stamp(struct qla27xx_fwdt_template *tmp)
{
	tmp->capture_timestamp = jiffies;
}

static void
qla27xx_driver_info(struct qla27xx_fwdt_template *tmp)
{
	uint8_t v[] = { 0, 0, 0, 0, 0, 0 };

	sscanf(qla2x00_version_str, "%hhu.%hhu.%hhu.%hhu.%hhu.%hhu",
	    v+0, v+1, v+2, v+3, v+4, v+5);

	tmp->driver_info[0] = v[3] << 24 | v[2] << 16 | v[1] << 8 | v[0];
	tmp->driver_info[1] = v[5] << 8 | v[4];
	tmp->driver_info[2] = 0x12345678;
}

static void
qla27xx_firmware_info(struct scsi_qla_host *vha,
    struct qla27xx_fwdt_template *tmp)
{
	tmp->firmware_version[0] = vha->hw->fw_major_version;
	tmp->firmware_version[1] = vha->hw->fw_minor_version;
	tmp->firmware_version[2] = vha->hw->fw_subminor_version;
	tmp->firmware_version[3] =
	    vha->hw->fw_attributes_h << 16 | vha->hw->fw_attributes;
	tmp->firmware_version[4] =
	    vha->hw->fw_attributes_ext[1] << 16 | vha->hw->fw_attributes_ext[0];
}

static void
ql27xx_edit_template(struct scsi_qla_host *vha,
	struct qla27xx_fwdt_template *tmp)
{
	qla27xx_time_stamp(tmp);
	qla27xx_driver_info(tmp);
	qla27xx_firmware_info(vha, tmp);
}

static inline uint32_t
qla27xx_template_checksum(void *p, ulong size)
{
	__le32 *buf = p;
	uint64_t sum = 0;

	size /= sizeof(*buf);

	for ( ; size--; buf++)
		sum += le32_to_cpu(*buf);

	sum = (sum & 0xffffffff) + (sum >> 32);

	return ~sum;
}

static inline int
qla27xx_verify_template_checksum(struct qla27xx_fwdt_template *tmp)
{
	return qla27xx_template_checksum(tmp, tmp->template_size) == 0;
}

static inline int
qla27xx_verify_template_header(struct qla27xx_fwdt_template *tmp)
{
	return le32_to_cpu(tmp->template_type) == TEMPLATE_TYPE_FWDUMP;
}

static ulong
qla27xx_execute_fwdt_template(struct scsi_qla_host *vha,
    struct qla27xx_fwdt_template *tmp, void *buf)
{
	ulong len = 0;

	if (qla27xx_fwdt_template_valid(tmp)) {
		len = tmp->template_size;
		tmp = memcpy(buf, tmp, len);
		ql27xx_edit_template(vha, tmp);
		qla27xx_walk_template(vha, tmp, buf, &len);
	}

	return len;
}

ulong
qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *vha, void *p)
{
	struct qla27xx_fwdt_template *tmp = p;
	ulong len = 0;

	if (qla27xx_fwdt_template_valid(tmp)) {
		len = tmp->template_size;
		qla27xx_walk_template(vha, tmp, NULL, &len);
	}

	return len;
}

ulong
qla27xx_fwdt_template_size(void *p)
{
	struct qla27xx_fwdt_template *tmp = p;

	return tmp->template_size;
}

int
qla27xx_fwdt_template_valid(void *p)
{
	struct qla27xx_fwdt_template *tmp = p;

	if (!qla27xx_verify_template_header(tmp)) {
		ql_log(ql_log_warn, NULL, 0xd01c,
		    "%s: template type %x\n", __func__,
		    le32_to_cpu(tmp->template_type));
		return false;
	}

	if (!qla27xx_verify_template_checksum(tmp)) {
		ql_log(ql_log_warn, NULL, 0xd01d,
		    "%s: failed template checksum\n", __func__);
		return false;
	}

	return true;
}

void
qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked)
{
	ulong flags = 0;

#ifndef __CHECKER__
	if (!hardware_locked)
		spin_lock_irqsave(&vha->hw->hardware_lock, flags);
#endif

	if (!vha->hw->fw_dump) {
		ql_log(ql_log_warn, vha, 0xd01e, "-> fwdump no buffer\n");
	} else if (vha->hw->fw_dumped) {
		ql_log(ql_log_warn, vha, 0xd01f,
		    "-> Firmware already dumped (%p) -- ignoring request\n",
		    vha->hw->fw_dump);
	} else {
		struct fwdt *fwdt = vha->hw->fwdt;
		uint j;
		ulong len;
		void *buf = vha->hw->fw_dump;

		for (j = 0; j < 2; j++, fwdt++, buf += len) {
			ql_log(ql_log_warn, vha, 0xd011,
			    "-> fwdt%u running...\n", j);
			if (!fwdt->template) {
				ql_log(ql_log_warn, vha, 0xd012,
				    "-> fwdt%u no template\n", j);
				break;
			}
			len = qla27xx_execute_fwdt_template(vha,
			    fwdt->template, buf);
			if (len != fwdt->dump_size) {
				ql_log(ql_log_warn, vha, 0xd013,
				    "-> fwdt%u fwdump residual=%+ld\n",
				    j, fwdt->dump_size - len);
			}
		}
		vha->hw->fw_dump_len = buf - (void *)vha->hw->fw_dump;
		vha->hw->fw_dumped = 1;

		ql_log(ql_log_warn, vha, 0xd015,
		    "-> Firmware dump saved to buffer (%lu/%p) <%lx>\n",
		    vha->host_no, vha->hw->fw_dump, vha->hw->fw_dump_cap_flags);
		qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
	}

#ifndef __CHECKER__
	if (!hardware_locked)
		spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
#endif
}
