162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * QLogic Fibre Channel HBA Driver
462306a36Sopenharmony_ci * Copyright (c)  2003-2014 QLogic Corporation
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci/*
862306a36Sopenharmony_ci * Table for showing the current message id in use for particular level
962306a36Sopenharmony_ci * Change this table for addition of log/debug messages.
1062306a36Sopenharmony_ci * ----------------------------------------------------------------------
1162306a36Sopenharmony_ci * |             Level            |   Last Value Used  |     Holes	|
1262306a36Sopenharmony_ci * ----------------------------------------------------------------------
1362306a36Sopenharmony_ci * | Module Init and Probe        |       0x0199       |                |
1462306a36Sopenharmony_ci * | Mailbox commands             |       0x1206       | 0x11a5-0x11ff	|
1562306a36Sopenharmony_ci * | Device Discovery             |       0x2134       | 0x2112-0x2115  |
1662306a36Sopenharmony_ci * |                              |                    | 0x2127-0x2128  |
1762306a36Sopenharmony_ci * | Queue Command and IO tracing |       0x3074       | 0x300b         |
1862306a36Sopenharmony_ci * |                              |                    | 0x3027-0x3028  |
1962306a36Sopenharmony_ci * |                              |                    | 0x303d-0x3041  |
2062306a36Sopenharmony_ci * |                              |                    | 0x302e,0x3033  |
2162306a36Sopenharmony_ci * |                              |                    | 0x3036,0x3038  |
2262306a36Sopenharmony_ci * |                              |                    | 0x303a		|
2362306a36Sopenharmony_ci * | DPC Thread                   |       0x4023       | 0x4002,0x4013  |
2462306a36Sopenharmony_ci * | Async Events                 |       0x509c       |                |
2562306a36Sopenharmony_ci * | Timer Routines               |       0x6012       |                |
2662306a36Sopenharmony_ci * | User Space Interactions      |       0x70e3       | 0x7018,0x702e  |
2762306a36Sopenharmony_ci * |				  |		       | 0x7020,0x7024  |
2862306a36Sopenharmony_ci * |                              |                    | 0x7039,0x7045  |
2962306a36Sopenharmony_ci * |                              |                    | 0x7073-0x7075  |
3062306a36Sopenharmony_ci * |                              |                    | 0x70a5-0x70a6  |
3162306a36Sopenharmony_ci * |                              |                    | 0x70a8,0x70ab  |
3262306a36Sopenharmony_ci * |                              |                    | 0x70ad-0x70ae  |
3362306a36Sopenharmony_ci * |                              |                    | 0x70d0-0x70d6	|
3462306a36Sopenharmony_ci * |                              |                    | 0x70d7-0x70db  |
3562306a36Sopenharmony_ci * | Task Management              |       0x8042       | 0x8000         |
3662306a36Sopenharmony_ci * |                              |                    | 0x8019         |
3762306a36Sopenharmony_ci * |                              |                    | 0x8025,0x8026  |
3862306a36Sopenharmony_ci * |                              |                    | 0x8031,0x8032  |
3962306a36Sopenharmony_ci * |                              |                    | 0x8039,0x803c  |
4062306a36Sopenharmony_ci * | AER/EEH                      |       0x9011       |		|
4162306a36Sopenharmony_ci * | Virtual Port                 |       0xa007       |		|
4262306a36Sopenharmony_ci * | ISP82XX Specific             |       0xb157       | 0xb002,0xb024  |
4362306a36Sopenharmony_ci * |                              |                    | 0xb09e,0xb0ae  |
4462306a36Sopenharmony_ci * |				  |		       | 0xb0c3,0xb0c6  |
4562306a36Sopenharmony_ci * |                              |                    | 0xb0e0-0xb0ef  |
4662306a36Sopenharmony_ci * |                              |                    | 0xb085,0xb0dc  |
4762306a36Sopenharmony_ci * |                              |                    | 0xb107,0xb108  |
4862306a36Sopenharmony_ci * |                              |                    | 0xb111,0xb11e  |
4962306a36Sopenharmony_ci * |                              |                    | 0xb12c,0xb12d  |
5062306a36Sopenharmony_ci * |                              |                    | 0xb13a,0xb142  |
5162306a36Sopenharmony_ci * |                              |                    | 0xb13c-0xb140  |
5262306a36Sopenharmony_ci * |                              |                    | 0xb149		|
5362306a36Sopenharmony_ci * | MultiQ                       |       0xc010       |		|
5462306a36Sopenharmony_ci * | Misc                         |       0xd303       | 0xd031-0xd0ff	|
5562306a36Sopenharmony_ci * |                              |                    | 0xd101-0xd1fe	|
5662306a36Sopenharmony_ci * |                              |                    | 0xd214-0xd2fe	|
5762306a36Sopenharmony_ci * | Target Mode		  |	  0xe081       |		|
5862306a36Sopenharmony_ci * | Target Mode Management	  |	  0xf09b       | 0xf002		|
5962306a36Sopenharmony_ci * |                              |                    | 0xf046-0xf049  |
6062306a36Sopenharmony_ci * | Target Mode Task Management  |	  0x1000d      |		|
6162306a36Sopenharmony_ci * ----------------------------------------------------------------------
6262306a36Sopenharmony_ci */
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci#include "qla_def.h"
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#include <linux/delay.h>
6762306a36Sopenharmony_ci#define CREATE_TRACE_POINTS
6862306a36Sopenharmony_ci#include <trace/events/qla.h>
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic uint32_t ql_dbg_offset = 0x800;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_cistatic inline void
7362306a36Sopenharmony_ciqla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	fw_dump->fw_major_version = htonl(ha->fw_major_version);
7662306a36Sopenharmony_ci	fw_dump->fw_minor_version = htonl(ha->fw_minor_version);
7762306a36Sopenharmony_ci	fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version);
7862306a36Sopenharmony_ci	fw_dump->fw_attributes = htonl(ha->fw_attributes);
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	fw_dump->vendor = htonl(ha->pdev->vendor);
8162306a36Sopenharmony_ci	fw_dump->device = htonl(ha->pdev->device);
8262306a36Sopenharmony_ci	fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor);
8362306a36Sopenharmony_ci	fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device);
8462306a36Sopenharmony_ci}
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_cistatic inline void *
8762306a36Sopenharmony_ciqla2xxx_copy_queues(struct qla_hw_data *ha, void *ptr)
8862306a36Sopenharmony_ci{
8962306a36Sopenharmony_ci	struct req_que *req = ha->req_q_map[0];
9062306a36Sopenharmony_ci	struct rsp_que *rsp = ha->rsp_q_map[0];
9162306a36Sopenharmony_ci	/* Request queue. */
9262306a36Sopenharmony_ci	memcpy(ptr, req->ring, req->length *
9362306a36Sopenharmony_ci	    sizeof(request_t));
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	/* Response queue. */
9662306a36Sopenharmony_ci	ptr += req->length * sizeof(request_t);
9762306a36Sopenharmony_ci	memcpy(ptr, rsp->ring, rsp->length  *
9862306a36Sopenharmony_ci	    sizeof(response_t));
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	return ptr + (rsp->length * sizeof(response_t));
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ciint
10462306a36Sopenharmony_ciqla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
10562306a36Sopenharmony_ci	uint32_t ram_dwords, void **nxt)
10662306a36Sopenharmony_ci{
10762306a36Sopenharmony_ci	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
10862306a36Sopenharmony_ci	dma_addr_t dump_dma = ha->gid_list_dma;
10962306a36Sopenharmony_ci	uint32_t *chunk = (uint32_t *)ha->gid_list;
11062306a36Sopenharmony_ci	uint32_t dwords = qla2x00_gid_list_size(ha) / 4;
11162306a36Sopenharmony_ci	uint32_t stat;
11262306a36Sopenharmony_ci	ulong i, j, timer = 6000000;
11362306a36Sopenharmony_ci	int rval = QLA_FUNCTION_FAILED;
11462306a36Sopenharmony_ci	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	if (qla_pci_disconnected(vha, reg))
11962306a36Sopenharmony_ci		return rval;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	for (i = 0; i < ram_dwords; i += dwords, addr += dwords) {
12262306a36Sopenharmony_ci		if (i + dwords > ram_dwords)
12362306a36Sopenharmony_ci			dwords = ram_dwords - i;
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox0, MBC_LOAD_DUMP_MPI_RAM);
12662306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox1, LSW(addr));
12762306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox8, MSW(addr));
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox2, MSW(LSD(dump_dma)));
13062306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox3, LSW(LSD(dump_dma)));
13162306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox6, MSW(MSD(dump_dma)));
13262306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox7, LSW(MSD(dump_dma)));
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox4, MSW(dwords));
13562306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox5, LSW(dwords));
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox9, 0);
13862306a36Sopenharmony_ci		wrt_reg_dword(&reg->hccr, HCCRX_SET_HOST_INT);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci		ha->flags.mbox_int = 0;
14162306a36Sopenharmony_ci		while (timer--) {
14262306a36Sopenharmony_ci			udelay(5);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci			if (qla_pci_disconnected(vha, reg))
14562306a36Sopenharmony_ci				return rval;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci			stat = rd_reg_dword(&reg->host_status);
14862306a36Sopenharmony_ci			/* Check for pending interrupts. */
14962306a36Sopenharmony_ci			if (!(stat & HSRX_RISC_INT))
15062306a36Sopenharmony_ci				continue;
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci			stat &= 0xff;
15362306a36Sopenharmony_ci			if (stat != 0x1 && stat != 0x2 &&
15462306a36Sopenharmony_ci			    stat != 0x10 && stat != 0x11) {
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci				/* Clear this intr; it wasn't a mailbox intr */
15762306a36Sopenharmony_ci				wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_INT);
15862306a36Sopenharmony_ci				rd_reg_dword(&reg->hccr);
15962306a36Sopenharmony_ci				continue;
16062306a36Sopenharmony_ci			}
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci			set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
16362306a36Sopenharmony_ci			rval = rd_reg_word(&reg->mailbox0) & MBS_MASK;
16462306a36Sopenharmony_ci			wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_INT);
16562306a36Sopenharmony_ci			rd_reg_dword(&reg->hccr);
16662306a36Sopenharmony_ci			break;
16762306a36Sopenharmony_ci		}
16862306a36Sopenharmony_ci		ha->flags.mbox_int = 1;
16962306a36Sopenharmony_ci		*nxt = ram + i;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci		if (!test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
17262306a36Sopenharmony_ci			/* no interrupt, timed out*/
17362306a36Sopenharmony_ci			return rval;
17462306a36Sopenharmony_ci		}
17562306a36Sopenharmony_ci		if (rval) {
17662306a36Sopenharmony_ci			/* error completion status */
17762306a36Sopenharmony_ci			return rval;
17862306a36Sopenharmony_ci		}
17962306a36Sopenharmony_ci		for (j = 0; j < dwords; j++) {
18062306a36Sopenharmony_ci			ram[i + j] =
18162306a36Sopenharmony_ci			    (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ?
18262306a36Sopenharmony_ci			    chunk[j] : swab32(chunk[j]);
18362306a36Sopenharmony_ci		}
18462306a36Sopenharmony_ci	}
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	*nxt = ram + i;
18762306a36Sopenharmony_ci	return QLA_SUCCESS;
18862306a36Sopenharmony_ci}
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ciint
19162306a36Sopenharmony_ciqla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be32 *ram,
19262306a36Sopenharmony_ci		 uint32_t ram_dwords, void **nxt)
19362306a36Sopenharmony_ci{
19462306a36Sopenharmony_ci	int rval = QLA_FUNCTION_FAILED;
19562306a36Sopenharmony_ci	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
19662306a36Sopenharmony_ci	dma_addr_t dump_dma = ha->gid_list_dma;
19762306a36Sopenharmony_ci	uint32_t *chunk = (uint32_t *)ha->gid_list;
19862306a36Sopenharmony_ci	uint32_t dwords = qla2x00_gid_list_size(ha) / 4;
19962306a36Sopenharmony_ci	uint32_t stat;
20062306a36Sopenharmony_ci	ulong i, j, timer = 6000000;
20162306a36Sopenharmony_ci	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	if (qla_pci_disconnected(vha, reg))
20662306a36Sopenharmony_ci		return rval;
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	for (i = 0; i < ram_dwords; i += dwords, addr += dwords) {
20962306a36Sopenharmony_ci		if (i + dwords > ram_dwords)
21062306a36Sopenharmony_ci			dwords = ram_dwords - i;
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED);
21362306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox1, LSW(addr));
21462306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox8, MSW(addr));
21562306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox10, 0);
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox2, MSW(LSD(dump_dma)));
21862306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox3, LSW(LSD(dump_dma)));
21962306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox6, MSW(MSD(dump_dma)));
22062306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox7, LSW(MSD(dump_dma)));
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox4, MSW(dwords));
22362306a36Sopenharmony_ci		wrt_reg_word(&reg->mailbox5, LSW(dwords));
22462306a36Sopenharmony_ci		wrt_reg_dword(&reg->hccr, HCCRX_SET_HOST_INT);
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci		ha->flags.mbox_int = 0;
22762306a36Sopenharmony_ci		while (timer--) {
22862306a36Sopenharmony_ci			udelay(5);
22962306a36Sopenharmony_ci			if (qla_pci_disconnected(vha, reg))
23062306a36Sopenharmony_ci				return rval;
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci			stat = rd_reg_dword(&reg->host_status);
23362306a36Sopenharmony_ci			/* Check for pending interrupts. */
23462306a36Sopenharmony_ci			if (!(stat & HSRX_RISC_INT))
23562306a36Sopenharmony_ci				continue;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci			stat &= 0xff;
23862306a36Sopenharmony_ci			if (stat != 0x1 && stat != 0x2 &&
23962306a36Sopenharmony_ci			    stat != 0x10 && stat != 0x11) {
24062306a36Sopenharmony_ci				wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_INT);
24162306a36Sopenharmony_ci				rd_reg_dword(&reg->hccr);
24262306a36Sopenharmony_ci				continue;
24362306a36Sopenharmony_ci			}
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci			set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
24662306a36Sopenharmony_ci			rval = rd_reg_word(&reg->mailbox0) & MBS_MASK;
24762306a36Sopenharmony_ci			wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_INT);
24862306a36Sopenharmony_ci			rd_reg_dword(&reg->hccr);
24962306a36Sopenharmony_ci			break;
25062306a36Sopenharmony_ci		}
25162306a36Sopenharmony_ci		ha->flags.mbox_int = 1;
25262306a36Sopenharmony_ci		*nxt = ram + i;
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci		if (!test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
25562306a36Sopenharmony_ci			/* no interrupt, timed out*/
25662306a36Sopenharmony_ci			return rval;
25762306a36Sopenharmony_ci		}
25862306a36Sopenharmony_ci		if (rval) {
25962306a36Sopenharmony_ci			/* error completion status */
26062306a36Sopenharmony_ci			return rval;
26162306a36Sopenharmony_ci		}
26262306a36Sopenharmony_ci		for (j = 0; j < dwords; j++) {
26362306a36Sopenharmony_ci			ram[i + j] = (__force __be32)
26462306a36Sopenharmony_ci				((IS_QLA27XX(ha) || IS_QLA28XX(ha)) ?
26562306a36Sopenharmony_ci				 chunk[j] : swab32(chunk[j]));
26662306a36Sopenharmony_ci		}
26762306a36Sopenharmony_ci	}
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	*nxt = ram + i;
27062306a36Sopenharmony_ci	return QLA_SUCCESS;
27162306a36Sopenharmony_ci}
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_cistatic int
27462306a36Sopenharmony_ciqla24xx_dump_memory(struct qla_hw_data *ha, __be32 *code_ram,
27562306a36Sopenharmony_ci		    uint32_t cram_size, void **nxt)
27662306a36Sopenharmony_ci{
27762306a36Sopenharmony_ci	int rval;
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	/* Code RAM. */
28062306a36Sopenharmony_ci	rval = qla24xx_dump_ram(ha, 0x20000, code_ram, cram_size / 4, nxt);
28162306a36Sopenharmony_ci	if (rval != QLA_SUCCESS)
28262306a36Sopenharmony_ci		return rval;
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	set_bit(RISC_SRAM_DUMP_CMPL, &ha->fw_dump_cap_flags);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	/* External Memory. */
28762306a36Sopenharmony_ci	rval = qla24xx_dump_ram(ha, 0x100000, *nxt,
28862306a36Sopenharmony_ci	    ha->fw_memory_size - 0x100000 + 1, nxt);
28962306a36Sopenharmony_ci	if (rval == QLA_SUCCESS)
29062306a36Sopenharmony_ci		set_bit(RISC_EXT_MEM_DUMP_CMPL, &ha->fw_dump_cap_flags);
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci	return rval;
29362306a36Sopenharmony_ci}
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_cistatic __be32 *
29662306a36Sopenharmony_ciqla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase,
29762306a36Sopenharmony_ci		    uint32_t count, __be32 *buf)
29862306a36Sopenharmony_ci{
29962306a36Sopenharmony_ci	__le32 __iomem *dmp_reg;
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, iobase);
30262306a36Sopenharmony_ci	dmp_reg = &reg->iobase_window;
30362306a36Sopenharmony_ci	for ( ; count--; dmp_reg++)
30462306a36Sopenharmony_ci		*buf++ = htonl(rd_reg_dword(dmp_reg));
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	return buf;
30762306a36Sopenharmony_ci}
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_civoid
31062306a36Sopenharmony_ciqla24xx_pause_risc(struct device_reg_24xx __iomem *reg, struct qla_hw_data *ha)
31162306a36Sopenharmony_ci{
31262306a36Sopenharmony_ci	wrt_reg_dword(&reg->hccr, HCCRX_SET_RISC_PAUSE);
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci	/* 100 usec delay is sufficient enough for hardware to pause RISC */
31562306a36Sopenharmony_ci	udelay(100);
31662306a36Sopenharmony_ci	if (rd_reg_dword(&reg->host_status) & HSRX_RISC_PAUSED)
31762306a36Sopenharmony_ci		set_bit(RISC_PAUSE_CMPL, &ha->fw_dump_cap_flags);
31862306a36Sopenharmony_ci}
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ciint
32162306a36Sopenharmony_ciqla24xx_soft_reset(struct qla_hw_data *ha)
32262306a36Sopenharmony_ci{
32362306a36Sopenharmony_ci	int rval = QLA_SUCCESS;
32462306a36Sopenharmony_ci	uint32_t cnt;
32562306a36Sopenharmony_ci	uint16_t wd;
32662306a36Sopenharmony_ci	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	/*
32962306a36Sopenharmony_ci	 * Reset RISC. The delay is dependent on system architecture.
33062306a36Sopenharmony_ci	 * Driver can proceed with the reset sequence after waiting
33162306a36Sopenharmony_ci	 * for a timeout period.
33262306a36Sopenharmony_ci	 */
33362306a36Sopenharmony_ci	wrt_reg_dword(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
33462306a36Sopenharmony_ci	for (cnt = 0; cnt < 30000; cnt++) {
33562306a36Sopenharmony_ci		if ((rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
33662306a36Sopenharmony_ci			break;
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci		udelay(10);
33962306a36Sopenharmony_ci	}
34062306a36Sopenharmony_ci	if (!(rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE))
34162306a36Sopenharmony_ci		set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags);
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	wrt_reg_dword(&reg->ctrl_status,
34462306a36Sopenharmony_ci	    CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
34562306a36Sopenharmony_ci	pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	udelay(100);
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	/* Wait for soft-reset to complete. */
35062306a36Sopenharmony_ci	for (cnt = 0; cnt < 30000; cnt++) {
35162306a36Sopenharmony_ci		if ((rd_reg_dword(&reg->ctrl_status) &
35262306a36Sopenharmony_ci		    CSRX_ISP_SOFT_RESET) == 0)
35362306a36Sopenharmony_ci			break;
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci		udelay(10);
35662306a36Sopenharmony_ci	}
35762306a36Sopenharmony_ci	if (!(rd_reg_dword(&reg->ctrl_status) & CSRX_ISP_SOFT_RESET))
35862306a36Sopenharmony_ci		set_bit(ISP_RESET_CMPL, &ha->fw_dump_cap_flags);
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_RESET);
36162306a36Sopenharmony_ci	rd_reg_dword(&reg->hccr);             /* PCI Posting. */
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	for (cnt = 10000; rd_reg_word(&reg->mailbox0) != 0 &&
36462306a36Sopenharmony_ci	    rval == QLA_SUCCESS; cnt--) {
36562306a36Sopenharmony_ci		if (cnt)
36662306a36Sopenharmony_ci			udelay(10);
36762306a36Sopenharmony_ci		else
36862306a36Sopenharmony_ci			rval = QLA_FUNCTION_TIMEOUT;
36962306a36Sopenharmony_ci	}
37062306a36Sopenharmony_ci	if (rval == QLA_SUCCESS)
37162306a36Sopenharmony_ci		set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	return rval;
37462306a36Sopenharmony_ci}
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_cistatic int
37762306a36Sopenharmony_ciqla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be16 *ram,
37862306a36Sopenharmony_ci    uint32_t ram_words, void **nxt)
37962306a36Sopenharmony_ci{
38062306a36Sopenharmony_ci	int rval;
38162306a36Sopenharmony_ci	uint32_t cnt, stat, timer, words, idx;
38262306a36Sopenharmony_ci	uint16_t mb0;
38362306a36Sopenharmony_ci	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
38462306a36Sopenharmony_ci	dma_addr_t dump_dma = ha->gid_list_dma;
38562306a36Sopenharmony_ci	__le16 *dump = (__force __le16 *)ha->gid_list;
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	rval = QLA_SUCCESS;
38862306a36Sopenharmony_ci	mb0 = 0;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	WRT_MAILBOX_REG(ha, reg, 0, MBC_DUMP_RISC_RAM_EXTENDED);
39162306a36Sopenharmony_ci	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	words = qla2x00_gid_list_size(ha) / 2;
39462306a36Sopenharmony_ci	for (cnt = 0; cnt < ram_words && rval == QLA_SUCCESS;
39562306a36Sopenharmony_ci	    cnt += words, addr += words) {
39662306a36Sopenharmony_ci		if (cnt + words > ram_words)
39762306a36Sopenharmony_ci			words = ram_words - cnt;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci		WRT_MAILBOX_REG(ha, reg, 1, LSW(addr));
40062306a36Sopenharmony_ci		WRT_MAILBOX_REG(ha, reg, 8, MSW(addr));
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci		WRT_MAILBOX_REG(ha, reg, 2, MSW(dump_dma));
40362306a36Sopenharmony_ci		WRT_MAILBOX_REG(ha, reg, 3, LSW(dump_dma));
40462306a36Sopenharmony_ci		WRT_MAILBOX_REG(ha, reg, 6, MSW(MSD(dump_dma)));
40562306a36Sopenharmony_ci		WRT_MAILBOX_REG(ha, reg, 7, LSW(MSD(dump_dma)));
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci		WRT_MAILBOX_REG(ha, reg, 4, words);
40862306a36Sopenharmony_ci		wrt_reg_word(&reg->hccr, HCCR_SET_HOST_INT);
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci		for (timer = 6000000; timer; timer--) {
41162306a36Sopenharmony_ci			/* Check for pending interrupts. */
41262306a36Sopenharmony_ci			stat = rd_reg_dword(&reg->u.isp2300.host_status);
41362306a36Sopenharmony_ci			if (stat & HSR_RISC_INT) {
41462306a36Sopenharmony_ci				stat &= 0xff;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci				if (stat == 0x1 || stat == 0x2) {
41762306a36Sopenharmony_ci					set_bit(MBX_INTERRUPT,
41862306a36Sopenharmony_ci					    &ha->mbx_cmd_flags);
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci					mb0 = RD_MAILBOX_REG(ha, reg, 0);
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci					/* Release mailbox registers. */
42362306a36Sopenharmony_ci					wrt_reg_word(&reg->semaphore, 0);
42462306a36Sopenharmony_ci					wrt_reg_word(&reg->hccr,
42562306a36Sopenharmony_ci					    HCCR_CLR_RISC_INT);
42662306a36Sopenharmony_ci					rd_reg_word(&reg->hccr);
42762306a36Sopenharmony_ci					break;
42862306a36Sopenharmony_ci				} else if (stat == 0x10 || stat == 0x11) {
42962306a36Sopenharmony_ci					set_bit(MBX_INTERRUPT,
43062306a36Sopenharmony_ci					    &ha->mbx_cmd_flags);
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci					mb0 = RD_MAILBOX_REG(ha, reg, 0);
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci					wrt_reg_word(&reg->hccr,
43562306a36Sopenharmony_ci					    HCCR_CLR_RISC_INT);
43662306a36Sopenharmony_ci					rd_reg_word(&reg->hccr);
43762306a36Sopenharmony_ci					break;
43862306a36Sopenharmony_ci				}
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci				/* clear this intr; it wasn't a mailbox intr */
44162306a36Sopenharmony_ci				wrt_reg_word(&reg->hccr, HCCR_CLR_RISC_INT);
44262306a36Sopenharmony_ci				rd_reg_word(&reg->hccr);
44362306a36Sopenharmony_ci			}
44462306a36Sopenharmony_ci			udelay(5);
44562306a36Sopenharmony_ci		}
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
44862306a36Sopenharmony_ci			rval = mb0 & MBS_MASK;
44962306a36Sopenharmony_ci			for (idx = 0; idx < words; idx++)
45062306a36Sopenharmony_ci				ram[cnt + idx] =
45162306a36Sopenharmony_ci					cpu_to_be16(le16_to_cpu(dump[idx]));
45262306a36Sopenharmony_ci		} else {
45362306a36Sopenharmony_ci			rval = QLA_FUNCTION_FAILED;
45462306a36Sopenharmony_ci		}
45562306a36Sopenharmony_ci	}
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	*nxt = rval == QLA_SUCCESS ? &ram[cnt] : NULL;
45862306a36Sopenharmony_ci	return rval;
45962306a36Sopenharmony_ci}
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_cistatic inline void
46262306a36Sopenharmony_ciqla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count,
46362306a36Sopenharmony_ci		    __be16 *buf)
46462306a36Sopenharmony_ci{
46562306a36Sopenharmony_ci	__le16 __iomem *dmp_reg = &reg->u.isp2300.fb_cmd;
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	for ( ; count--; dmp_reg++)
46862306a36Sopenharmony_ci		*buf++ = htons(rd_reg_word(dmp_reg));
46962306a36Sopenharmony_ci}
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_cistatic inline void *
47262306a36Sopenharmony_ciqla24xx_copy_eft(struct qla_hw_data *ha, void *ptr)
47362306a36Sopenharmony_ci{
47462306a36Sopenharmony_ci	if (!ha->eft)
47562306a36Sopenharmony_ci		return ptr;
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci	memcpy(ptr, ha->eft, ntohl(ha->fw_dump->eft_size));
47862306a36Sopenharmony_ci	return ptr + ntohl(ha->fw_dump->eft_size);
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_cistatic inline void *
48262306a36Sopenharmony_ciqla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, __be32 **last_chain)
48362306a36Sopenharmony_ci{
48462306a36Sopenharmony_ci	uint32_t cnt;
48562306a36Sopenharmony_ci	__be32 *iter_reg;
48662306a36Sopenharmony_ci	struct qla2xxx_fce_chain *fcec = ptr;
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci	if (!ha->fce)
48962306a36Sopenharmony_ci		return ptr;
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	*last_chain = &fcec->type;
49262306a36Sopenharmony_ci	fcec->type = htonl(DUMP_CHAIN_FCE);
49362306a36Sopenharmony_ci	fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) +
49462306a36Sopenharmony_ci	    fce_calc_size(ha->fce_bufs));
49562306a36Sopenharmony_ci	fcec->size = htonl(fce_calc_size(ha->fce_bufs));
49662306a36Sopenharmony_ci	fcec->addr_l = htonl(LSD(ha->fce_dma));
49762306a36Sopenharmony_ci	fcec->addr_h = htonl(MSD(ha->fce_dma));
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	iter_reg = fcec->eregs;
50062306a36Sopenharmony_ci	for (cnt = 0; cnt < 8; cnt++)
50162306a36Sopenharmony_ci		*iter_reg++ = htonl(ha->fce_mb[cnt]);
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	memcpy(iter_reg, ha->fce, ntohl(fcec->size));
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci	return (char *)iter_reg + ntohl(fcec->size);
50662306a36Sopenharmony_ci}
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_cistatic inline void *
50962306a36Sopenharmony_ciqla25xx_copy_exlogin(struct qla_hw_data *ha, void *ptr, __be32 **last_chain)
51062306a36Sopenharmony_ci{
51162306a36Sopenharmony_ci	struct qla2xxx_offld_chain *c = ptr;
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci	if (!ha->exlogin_buf)
51462306a36Sopenharmony_ci		return ptr;
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	*last_chain = &c->type;
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	c->type = cpu_to_be32(DUMP_CHAIN_EXLOGIN);
51962306a36Sopenharmony_ci	c->chain_size = cpu_to_be32(sizeof(struct qla2xxx_offld_chain) +
52062306a36Sopenharmony_ci	    ha->exlogin_size);
52162306a36Sopenharmony_ci	c->size = cpu_to_be32(ha->exlogin_size);
52262306a36Sopenharmony_ci	c->addr = cpu_to_be64(ha->exlogin_buf_dma);
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	ptr += sizeof(struct qla2xxx_offld_chain);
52562306a36Sopenharmony_ci	memcpy(ptr, ha->exlogin_buf, ha->exlogin_size);
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci	return (char *)ptr + be32_to_cpu(c->size);
52862306a36Sopenharmony_ci}
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_cistatic inline void *
53162306a36Sopenharmony_ciqla81xx_copy_exchoffld(struct qla_hw_data *ha, void *ptr, __be32 **last_chain)
53262306a36Sopenharmony_ci{
53362306a36Sopenharmony_ci	struct qla2xxx_offld_chain *c = ptr;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	if (!ha->exchoffld_buf)
53662306a36Sopenharmony_ci		return ptr;
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	*last_chain = &c->type;
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	c->type = cpu_to_be32(DUMP_CHAIN_EXCHG);
54162306a36Sopenharmony_ci	c->chain_size = cpu_to_be32(sizeof(struct qla2xxx_offld_chain) +
54262306a36Sopenharmony_ci	    ha->exchoffld_size);
54362306a36Sopenharmony_ci	c->size = cpu_to_be32(ha->exchoffld_size);
54462306a36Sopenharmony_ci	c->addr = cpu_to_be64(ha->exchoffld_buf_dma);
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	ptr += sizeof(struct qla2xxx_offld_chain);
54762306a36Sopenharmony_ci	memcpy(ptr, ha->exchoffld_buf, ha->exchoffld_size);
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci	return (char *)ptr + be32_to_cpu(c->size);
55062306a36Sopenharmony_ci}
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_cistatic inline void *
55362306a36Sopenharmony_ciqla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr,
55462306a36Sopenharmony_ci			__be32 **last_chain)
55562306a36Sopenharmony_ci{
55662306a36Sopenharmony_ci	struct qla2xxx_mqueue_chain *q;
55762306a36Sopenharmony_ci	struct qla2xxx_mqueue_header *qh;
55862306a36Sopenharmony_ci	uint32_t num_queues;
55962306a36Sopenharmony_ci	int que;
56062306a36Sopenharmony_ci	struct {
56162306a36Sopenharmony_ci		int length;
56262306a36Sopenharmony_ci		void *ring;
56362306a36Sopenharmony_ci	} aq, *aqp;
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	if (!ha->tgt.atio_ring)
56662306a36Sopenharmony_ci		return ptr;
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci	num_queues = 1;
56962306a36Sopenharmony_ci	aqp = &aq;
57062306a36Sopenharmony_ci	aqp->length = ha->tgt.atio_q_length;
57162306a36Sopenharmony_ci	aqp->ring = ha->tgt.atio_ring;
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci	for (que = 0; que < num_queues; que++) {
57462306a36Sopenharmony_ci		/* aqp = ha->atio_q_map[que]; */
57562306a36Sopenharmony_ci		q = ptr;
57662306a36Sopenharmony_ci		*last_chain = &q->type;
57762306a36Sopenharmony_ci		q->type = htonl(DUMP_CHAIN_QUEUE);
57862306a36Sopenharmony_ci		q->chain_size = htonl(
57962306a36Sopenharmony_ci		    sizeof(struct qla2xxx_mqueue_chain) +
58062306a36Sopenharmony_ci		    sizeof(struct qla2xxx_mqueue_header) +
58162306a36Sopenharmony_ci		    (aqp->length * sizeof(request_t)));
58262306a36Sopenharmony_ci		ptr += sizeof(struct qla2xxx_mqueue_chain);
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci		/* Add header. */
58562306a36Sopenharmony_ci		qh = ptr;
58662306a36Sopenharmony_ci		qh->queue = htonl(TYPE_ATIO_QUEUE);
58762306a36Sopenharmony_ci		qh->number = htonl(que);
58862306a36Sopenharmony_ci		qh->size = htonl(aqp->length * sizeof(request_t));
58962306a36Sopenharmony_ci		ptr += sizeof(struct qla2xxx_mqueue_header);
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci		/* Add data. */
59262306a36Sopenharmony_ci		memcpy(ptr, aqp->ring, aqp->length * sizeof(request_t));
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci		ptr += aqp->length * sizeof(request_t);
59562306a36Sopenharmony_ci	}
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci	return ptr;
59862306a36Sopenharmony_ci}
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_cistatic inline void *
60162306a36Sopenharmony_ciqla25xx_copy_mqueues(struct qla_hw_data *ha, void *ptr, __be32 **last_chain)
60262306a36Sopenharmony_ci{
60362306a36Sopenharmony_ci	struct qla2xxx_mqueue_chain *q;
60462306a36Sopenharmony_ci	struct qla2xxx_mqueue_header *qh;
60562306a36Sopenharmony_ci	struct req_que *req;
60662306a36Sopenharmony_ci	struct rsp_que *rsp;
60762306a36Sopenharmony_ci	int que;
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_ci	if (!ha->mqenable)
61062306a36Sopenharmony_ci		return ptr;
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci	/* Request queues */
61362306a36Sopenharmony_ci	for (que = 1; que < ha->max_req_queues; que++) {
61462306a36Sopenharmony_ci		req = ha->req_q_map[que];
61562306a36Sopenharmony_ci		if (!req)
61662306a36Sopenharmony_ci			break;
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci		/* Add chain. */
61962306a36Sopenharmony_ci		q = ptr;
62062306a36Sopenharmony_ci		*last_chain = &q->type;
62162306a36Sopenharmony_ci		q->type = htonl(DUMP_CHAIN_QUEUE);
62262306a36Sopenharmony_ci		q->chain_size = htonl(
62362306a36Sopenharmony_ci		    sizeof(struct qla2xxx_mqueue_chain) +
62462306a36Sopenharmony_ci		    sizeof(struct qla2xxx_mqueue_header) +
62562306a36Sopenharmony_ci		    (req->length * sizeof(request_t)));
62662306a36Sopenharmony_ci		ptr += sizeof(struct qla2xxx_mqueue_chain);
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci		/* Add header. */
62962306a36Sopenharmony_ci		qh = ptr;
63062306a36Sopenharmony_ci		qh->queue = htonl(TYPE_REQUEST_QUEUE);
63162306a36Sopenharmony_ci		qh->number = htonl(que);
63262306a36Sopenharmony_ci		qh->size = htonl(req->length * sizeof(request_t));
63362306a36Sopenharmony_ci		ptr += sizeof(struct qla2xxx_mqueue_header);
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci		/* Add data. */
63662306a36Sopenharmony_ci		memcpy(ptr, req->ring, req->length * sizeof(request_t));
63762306a36Sopenharmony_ci		ptr += req->length * sizeof(request_t);
63862306a36Sopenharmony_ci	}
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	/* Response queues */
64162306a36Sopenharmony_ci	for (que = 1; que < ha->max_rsp_queues; que++) {
64262306a36Sopenharmony_ci		rsp = ha->rsp_q_map[que];
64362306a36Sopenharmony_ci		if (!rsp)
64462306a36Sopenharmony_ci			break;
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci		/* Add chain. */
64762306a36Sopenharmony_ci		q = ptr;
64862306a36Sopenharmony_ci		*last_chain = &q->type;
64962306a36Sopenharmony_ci		q->type = htonl(DUMP_CHAIN_QUEUE);
65062306a36Sopenharmony_ci		q->chain_size = htonl(
65162306a36Sopenharmony_ci		    sizeof(struct qla2xxx_mqueue_chain) +
65262306a36Sopenharmony_ci		    sizeof(struct qla2xxx_mqueue_header) +
65362306a36Sopenharmony_ci		    (rsp->length * sizeof(response_t)));
65462306a36Sopenharmony_ci		ptr += sizeof(struct qla2xxx_mqueue_chain);
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci		/* Add header. */
65762306a36Sopenharmony_ci		qh = ptr;
65862306a36Sopenharmony_ci		qh->queue = htonl(TYPE_RESPONSE_QUEUE);
65962306a36Sopenharmony_ci		qh->number = htonl(que);
66062306a36Sopenharmony_ci		qh->size = htonl(rsp->length * sizeof(response_t));
66162306a36Sopenharmony_ci		ptr += sizeof(struct qla2xxx_mqueue_header);
66262306a36Sopenharmony_ci
66362306a36Sopenharmony_ci		/* Add data. */
66462306a36Sopenharmony_ci		memcpy(ptr, rsp->ring, rsp->length * sizeof(response_t));
66562306a36Sopenharmony_ci		ptr += rsp->length * sizeof(response_t);
66662306a36Sopenharmony_ci	}
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci	return ptr;
66962306a36Sopenharmony_ci}
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_cistatic inline void *
67262306a36Sopenharmony_ciqla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, __be32 **last_chain)
67362306a36Sopenharmony_ci{
67462306a36Sopenharmony_ci	uint32_t cnt, que_idx;
67562306a36Sopenharmony_ci	uint8_t que_cnt;
67662306a36Sopenharmony_ci	struct qla2xxx_mq_chain *mq = ptr;
67762306a36Sopenharmony_ci	device_reg_t *reg;
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	if (!ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
68062306a36Sopenharmony_ci	    IS_QLA28XX(ha))
68162306a36Sopenharmony_ci		return ptr;
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci	mq = ptr;
68462306a36Sopenharmony_ci	*last_chain = &mq->type;
68562306a36Sopenharmony_ci	mq->type = htonl(DUMP_CHAIN_MQ);
68662306a36Sopenharmony_ci	mq->chain_size = htonl(sizeof(struct qla2xxx_mq_chain));
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	que_cnt = ha->max_req_queues > ha->max_rsp_queues ?
68962306a36Sopenharmony_ci		ha->max_req_queues : ha->max_rsp_queues;
69062306a36Sopenharmony_ci	mq->count = htonl(que_cnt);
69162306a36Sopenharmony_ci	for (cnt = 0; cnt < que_cnt; cnt++) {
69262306a36Sopenharmony_ci		reg = ISP_QUE_REG(ha, cnt);
69362306a36Sopenharmony_ci		que_idx = cnt * 4;
69462306a36Sopenharmony_ci		mq->qregs[que_idx] =
69562306a36Sopenharmony_ci		    htonl(rd_reg_dword(&reg->isp25mq.req_q_in));
69662306a36Sopenharmony_ci		mq->qregs[que_idx+1] =
69762306a36Sopenharmony_ci		    htonl(rd_reg_dword(&reg->isp25mq.req_q_out));
69862306a36Sopenharmony_ci		mq->qregs[que_idx+2] =
69962306a36Sopenharmony_ci		    htonl(rd_reg_dword(&reg->isp25mq.rsp_q_in));
70062306a36Sopenharmony_ci		mq->qregs[que_idx+3] =
70162306a36Sopenharmony_ci		    htonl(rd_reg_dword(&reg->isp25mq.rsp_q_out));
70262306a36Sopenharmony_ci	}
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ci	return ptr + sizeof(struct qla2xxx_mq_chain);
70562306a36Sopenharmony_ci}
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_civoid
70862306a36Sopenharmony_ciqla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
70962306a36Sopenharmony_ci{
71062306a36Sopenharmony_ci	struct qla_hw_data *ha = vha->hw;
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci	if (rval != QLA_SUCCESS) {
71362306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd000,
71462306a36Sopenharmony_ci		    "Failed to dump firmware (%x), dump status flags (0x%lx).\n",
71562306a36Sopenharmony_ci		    rval, ha->fw_dump_cap_flags);
71662306a36Sopenharmony_ci		ha->fw_dumped = false;
71762306a36Sopenharmony_ci	} else {
71862306a36Sopenharmony_ci		ql_log(ql_log_info, vha, 0xd001,
71962306a36Sopenharmony_ci		    "Firmware dump saved to temp buffer (%ld/%p), dump status flags (0x%lx).\n",
72062306a36Sopenharmony_ci		    vha->host_no, ha->fw_dump, ha->fw_dump_cap_flags);
72162306a36Sopenharmony_ci		ha->fw_dumped = true;
72262306a36Sopenharmony_ci		qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
72362306a36Sopenharmony_ci	}
72462306a36Sopenharmony_ci}
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_civoid qla2xxx_dump_fw(scsi_qla_host_t *vha)
72762306a36Sopenharmony_ci{
72862306a36Sopenharmony_ci	unsigned long flags;
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	spin_lock_irqsave(&vha->hw->hardware_lock, flags);
73162306a36Sopenharmony_ci	vha->hw->isp_ops->fw_dump(vha);
73262306a36Sopenharmony_ci	spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
73362306a36Sopenharmony_ci}
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_ci/**
73662306a36Sopenharmony_ci * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
73762306a36Sopenharmony_ci * @vha: HA context
73862306a36Sopenharmony_ci */
73962306a36Sopenharmony_civoid
74062306a36Sopenharmony_ciqla2300_fw_dump(scsi_qla_host_t *vha)
74162306a36Sopenharmony_ci{
74262306a36Sopenharmony_ci	int		rval;
74362306a36Sopenharmony_ci	uint32_t	cnt;
74462306a36Sopenharmony_ci	struct qla_hw_data *ha = vha->hw;
74562306a36Sopenharmony_ci	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
74662306a36Sopenharmony_ci	__le16 __iomem *dmp_reg;
74762306a36Sopenharmony_ci	struct qla2300_fw_dump	*fw;
74862306a36Sopenharmony_ci	void		*nxt;
74962306a36Sopenharmony_ci	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	lockdep_assert_held(&ha->hardware_lock);
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci	if (!ha->fw_dump) {
75462306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd002,
75562306a36Sopenharmony_ci		    "No buffer available for dump.\n");
75662306a36Sopenharmony_ci		return;
75762306a36Sopenharmony_ci	}
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	if (ha->fw_dumped) {
76062306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd003,
76162306a36Sopenharmony_ci		    "Firmware has been previously dumped (%p) "
76262306a36Sopenharmony_ci		    "-- ignoring request.\n",
76362306a36Sopenharmony_ci		    ha->fw_dump);
76462306a36Sopenharmony_ci		return;
76562306a36Sopenharmony_ci	}
76662306a36Sopenharmony_ci	fw = &ha->fw_dump->isp.isp23;
76762306a36Sopenharmony_ci	qla2xxx_prep_dump(ha, ha->fw_dump);
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	rval = QLA_SUCCESS;
77062306a36Sopenharmony_ci	fw->hccr = htons(rd_reg_word(&reg->hccr));
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci	/* Pause RISC. */
77362306a36Sopenharmony_ci	wrt_reg_word(&reg->hccr, HCCR_PAUSE_RISC);
77462306a36Sopenharmony_ci	if (IS_QLA2300(ha)) {
77562306a36Sopenharmony_ci		for (cnt = 30000;
77662306a36Sopenharmony_ci		    (rd_reg_word(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
77762306a36Sopenharmony_ci			rval == QLA_SUCCESS; cnt--) {
77862306a36Sopenharmony_ci			if (cnt)
77962306a36Sopenharmony_ci				udelay(100);
78062306a36Sopenharmony_ci			else
78162306a36Sopenharmony_ci				rval = QLA_FUNCTION_TIMEOUT;
78262306a36Sopenharmony_ci		}
78362306a36Sopenharmony_ci	} else {
78462306a36Sopenharmony_ci		rd_reg_word(&reg->hccr);		/* PCI Posting. */
78562306a36Sopenharmony_ci		udelay(10);
78662306a36Sopenharmony_ci	}
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_ci	if (rval == QLA_SUCCESS) {
78962306a36Sopenharmony_ci		dmp_reg = &reg->flash_address;
79062306a36Sopenharmony_ci		for (cnt = 0; cnt < ARRAY_SIZE(fw->pbiu_reg); cnt++, dmp_reg++)
79162306a36Sopenharmony_ci			fw->pbiu_reg[cnt] = htons(rd_reg_word(dmp_reg));
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_ci		dmp_reg = &reg->u.isp2300.req_q_in;
79462306a36Sopenharmony_ci		for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_host_reg);
79562306a36Sopenharmony_ci		    cnt++, dmp_reg++)
79662306a36Sopenharmony_ci			fw->risc_host_reg[cnt] = htons(rd_reg_word(dmp_reg));
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ci		dmp_reg = &reg->u.isp2300.mailbox0;
79962306a36Sopenharmony_ci		for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg);
80062306a36Sopenharmony_ci		    cnt++, dmp_reg++)
80162306a36Sopenharmony_ci			fw->mailbox_reg[cnt] = htons(rd_reg_word(dmp_reg));
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, 0x40);
80462306a36Sopenharmony_ci		qla2xxx_read_window(reg, 32, fw->resp_dma_reg);
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, 0x50);
80762306a36Sopenharmony_ci		qla2xxx_read_window(reg, 48, fw->dma_reg);
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, 0x00);
81062306a36Sopenharmony_ci		dmp_reg = &reg->risc_hw;
81162306a36Sopenharmony_ci		for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_hdw_reg);
81262306a36Sopenharmony_ci		    cnt++, dmp_reg++)
81362306a36Sopenharmony_ci			fw->risc_hdw_reg[cnt] = htons(rd_reg_word(dmp_reg));
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2000);
81662306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2200);
81962306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2400);
82262306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2600);
82562306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2800);
82862306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2A00);
83162306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2C00);
83462306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2E00);
83762306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, 0x10);
84062306a36Sopenharmony_ci		qla2xxx_read_window(reg, 64, fw->frame_buf_hdw_reg);
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, 0x20);
84362306a36Sopenharmony_ci		qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);
84462306a36Sopenharmony_ci
84562306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, 0x30);
84662306a36Sopenharmony_ci		qla2xxx_read_window(reg, 64, fw->fpm_b1_reg);
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ci		/* Reset RISC. */
84962306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
85062306a36Sopenharmony_ci		for (cnt = 0; cnt < 30000; cnt++) {
85162306a36Sopenharmony_ci			if ((rd_reg_word(&reg->ctrl_status) &
85262306a36Sopenharmony_ci			    CSR_ISP_SOFT_RESET) == 0)
85362306a36Sopenharmony_ci				break;
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_ci			udelay(10);
85662306a36Sopenharmony_ci		}
85762306a36Sopenharmony_ci	}
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_ci	if (!IS_QLA2300(ha)) {
86062306a36Sopenharmony_ci		for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
86162306a36Sopenharmony_ci		    rval == QLA_SUCCESS; cnt--) {
86262306a36Sopenharmony_ci			if (cnt)
86362306a36Sopenharmony_ci				udelay(100);
86462306a36Sopenharmony_ci			else
86562306a36Sopenharmony_ci				rval = QLA_FUNCTION_TIMEOUT;
86662306a36Sopenharmony_ci		}
86762306a36Sopenharmony_ci	}
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci	/* Get RISC SRAM. */
87062306a36Sopenharmony_ci	if (rval == QLA_SUCCESS)
87162306a36Sopenharmony_ci		rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram,
87262306a36Sopenharmony_ci					ARRAY_SIZE(fw->risc_ram), &nxt);
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci	/* Get stack SRAM. */
87562306a36Sopenharmony_ci	if (rval == QLA_SUCCESS)
87662306a36Sopenharmony_ci		rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram,
87762306a36Sopenharmony_ci					ARRAY_SIZE(fw->stack_ram), &nxt);
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci	/* Get data SRAM. */
88062306a36Sopenharmony_ci	if (rval == QLA_SUCCESS)
88162306a36Sopenharmony_ci		rval = qla2xxx_dump_ram(ha, 0x11000, fw->data_ram,
88262306a36Sopenharmony_ci		    ha->fw_memory_size - 0x11000 + 1, &nxt);
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_ci	if (rval == QLA_SUCCESS)
88562306a36Sopenharmony_ci		qla2xxx_copy_queues(ha, nxt);
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_ci	qla2xxx_dump_post_process(base_vha, rval);
88862306a36Sopenharmony_ci}
88962306a36Sopenharmony_ci
89062306a36Sopenharmony_ci/**
89162306a36Sopenharmony_ci * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware.
89262306a36Sopenharmony_ci * @vha: HA context
89362306a36Sopenharmony_ci */
89462306a36Sopenharmony_civoid
89562306a36Sopenharmony_ciqla2100_fw_dump(scsi_qla_host_t *vha)
89662306a36Sopenharmony_ci{
89762306a36Sopenharmony_ci	int		rval;
89862306a36Sopenharmony_ci	uint32_t	cnt, timer;
89962306a36Sopenharmony_ci	uint16_t	risc_address = 0;
90062306a36Sopenharmony_ci	uint16_t	mb0 = 0, mb2 = 0;
90162306a36Sopenharmony_ci	struct qla_hw_data *ha = vha->hw;
90262306a36Sopenharmony_ci	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
90362306a36Sopenharmony_ci	__le16 __iomem *dmp_reg;
90462306a36Sopenharmony_ci	struct qla2100_fw_dump	*fw;
90562306a36Sopenharmony_ci	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_ci	lockdep_assert_held(&ha->hardware_lock);
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_ci	if (!ha->fw_dump) {
91062306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd004,
91162306a36Sopenharmony_ci		    "No buffer available for dump.\n");
91262306a36Sopenharmony_ci		return;
91362306a36Sopenharmony_ci	}
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci	if (ha->fw_dumped) {
91662306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd005,
91762306a36Sopenharmony_ci		    "Firmware has been previously dumped (%p) "
91862306a36Sopenharmony_ci		    "-- ignoring request.\n",
91962306a36Sopenharmony_ci		    ha->fw_dump);
92062306a36Sopenharmony_ci		return;
92162306a36Sopenharmony_ci	}
92262306a36Sopenharmony_ci	fw = &ha->fw_dump->isp.isp21;
92362306a36Sopenharmony_ci	qla2xxx_prep_dump(ha, ha->fw_dump);
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci	rval = QLA_SUCCESS;
92662306a36Sopenharmony_ci	fw->hccr = htons(rd_reg_word(&reg->hccr));
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ci	/* Pause RISC. */
92962306a36Sopenharmony_ci	wrt_reg_word(&reg->hccr, HCCR_PAUSE_RISC);
93062306a36Sopenharmony_ci	for (cnt = 30000; (rd_reg_word(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
93162306a36Sopenharmony_ci	    rval == QLA_SUCCESS; cnt--) {
93262306a36Sopenharmony_ci		if (cnt)
93362306a36Sopenharmony_ci			udelay(100);
93462306a36Sopenharmony_ci		else
93562306a36Sopenharmony_ci			rval = QLA_FUNCTION_TIMEOUT;
93662306a36Sopenharmony_ci	}
93762306a36Sopenharmony_ci	if (rval == QLA_SUCCESS) {
93862306a36Sopenharmony_ci		dmp_reg = &reg->flash_address;
93962306a36Sopenharmony_ci		for (cnt = 0; cnt < ARRAY_SIZE(fw->pbiu_reg); cnt++, dmp_reg++)
94062306a36Sopenharmony_ci			fw->pbiu_reg[cnt] = htons(rd_reg_word(dmp_reg));
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_ci		dmp_reg = &reg->u.isp2100.mailbox0;
94362306a36Sopenharmony_ci		for (cnt = 0; cnt < ha->mbx_count; cnt++, dmp_reg++) {
94462306a36Sopenharmony_ci			if (cnt == 8)
94562306a36Sopenharmony_ci				dmp_reg = &reg->u_end.isp2200.mailbox8;
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci			fw->mailbox_reg[cnt] = htons(rd_reg_word(dmp_reg));
94862306a36Sopenharmony_ci		}
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci		dmp_reg = &reg->u.isp2100.unused_2[0];
95162306a36Sopenharmony_ci		for (cnt = 0; cnt < ARRAY_SIZE(fw->dma_reg); cnt++, dmp_reg++)
95262306a36Sopenharmony_ci			fw->dma_reg[cnt] = htons(rd_reg_word(dmp_reg));
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, 0x00);
95562306a36Sopenharmony_ci		dmp_reg = &reg->risc_hw;
95662306a36Sopenharmony_ci		for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_hdw_reg); cnt++, dmp_reg++)
95762306a36Sopenharmony_ci			fw->risc_hdw_reg[cnt] = htons(rd_reg_word(dmp_reg));
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2000);
96062306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);
96162306a36Sopenharmony_ci
96262306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2100);
96362306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2200);
96662306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);
96762306a36Sopenharmony_ci
96862306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2300);
96962306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2400);
97262306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2500);
97562306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2600);
97862306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);
97962306a36Sopenharmony_ci
98062306a36Sopenharmony_ci		wrt_reg_word(&reg->pcr, 0x2700);
98162306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, 0x10);
98462306a36Sopenharmony_ci		qla2xxx_read_window(reg, 16, fw->frame_buf_hdw_reg);
98562306a36Sopenharmony_ci
98662306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, 0x20);
98762306a36Sopenharmony_ci		qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, 0x30);
99062306a36Sopenharmony_ci		qla2xxx_read_window(reg, 64, fw->fpm_b1_reg);
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci		/* Reset the ISP. */
99362306a36Sopenharmony_ci		wrt_reg_word(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
99462306a36Sopenharmony_ci	}
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
99762306a36Sopenharmony_ci	    rval == QLA_SUCCESS; cnt--) {
99862306a36Sopenharmony_ci		if (cnt)
99962306a36Sopenharmony_ci			udelay(100);
100062306a36Sopenharmony_ci		else
100162306a36Sopenharmony_ci			rval = QLA_FUNCTION_TIMEOUT;
100262306a36Sopenharmony_ci	}
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	/* Pause RISC. */
100562306a36Sopenharmony_ci	if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) &&
100662306a36Sopenharmony_ci	    (rd_reg_word(&reg->mctr) & (BIT_1 | BIT_0)) != 0))) {
100762306a36Sopenharmony_ci
100862306a36Sopenharmony_ci		wrt_reg_word(&reg->hccr, HCCR_PAUSE_RISC);
100962306a36Sopenharmony_ci		for (cnt = 30000;
101062306a36Sopenharmony_ci		    (rd_reg_word(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
101162306a36Sopenharmony_ci		    rval == QLA_SUCCESS; cnt--) {
101262306a36Sopenharmony_ci			if (cnt)
101362306a36Sopenharmony_ci				udelay(100);
101462306a36Sopenharmony_ci			else
101562306a36Sopenharmony_ci				rval = QLA_FUNCTION_TIMEOUT;
101662306a36Sopenharmony_ci		}
101762306a36Sopenharmony_ci		if (rval == QLA_SUCCESS) {
101862306a36Sopenharmony_ci			/* Set memory configuration and timing. */
101962306a36Sopenharmony_ci			if (IS_QLA2100(ha))
102062306a36Sopenharmony_ci				wrt_reg_word(&reg->mctr, 0xf1);
102162306a36Sopenharmony_ci			else
102262306a36Sopenharmony_ci				wrt_reg_word(&reg->mctr, 0xf2);
102362306a36Sopenharmony_ci			rd_reg_word(&reg->mctr);	/* PCI Posting. */
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_ci			/* Release RISC. */
102662306a36Sopenharmony_ci			wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
102762306a36Sopenharmony_ci		}
102862306a36Sopenharmony_ci	}
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci	if (rval == QLA_SUCCESS) {
103162306a36Sopenharmony_ci		/* Get RISC SRAM. */
103262306a36Sopenharmony_ci		risc_address = 0x1000;
103362306a36Sopenharmony_ci 		WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
103462306a36Sopenharmony_ci		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
103562306a36Sopenharmony_ci	}
103662306a36Sopenharmony_ci	for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_ram) && rval == QLA_SUCCESS;
103762306a36Sopenharmony_ci	    cnt++, risc_address++) {
103862306a36Sopenharmony_ci 		WRT_MAILBOX_REG(ha, reg, 1, risc_address);
103962306a36Sopenharmony_ci		wrt_reg_word(&reg->hccr, HCCR_SET_HOST_INT);
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_ci		for (timer = 6000000; timer != 0; timer--) {
104262306a36Sopenharmony_ci			/* Check for pending interrupts. */
104362306a36Sopenharmony_ci			if (rd_reg_word(&reg->istatus) & ISR_RISC_INT) {
104462306a36Sopenharmony_ci				if (rd_reg_word(&reg->semaphore) & BIT_0) {
104562306a36Sopenharmony_ci					set_bit(MBX_INTERRUPT,
104662306a36Sopenharmony_ci					    &ha->mbx_cmd_flags);
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_ci					mb0 = RD_MAILBOX_REG(ha, reg, 0);
104962306a36Sopenharmony_ci					mb2 = RD_MAILBOX_REG(ha, reg, 2);
105062306a36Sopenharmony_ci
105162306a36Sopenharmony_ci					wrt_reg_word(&reg->semaphore, 0);
105262306a36Sopenharmony_ci					wrt_reg_word(&reg->hccr,
105362306a36Sopenharmony_ci					    HCCR_CLR_RISC_INT);
105462306a36Sopenharmony_ci					rd_reg_word(&reg->hccr);
105562306a36Sopenharmony_ci					break;
105662306a36Sopenharmony_ci				}
105762306a36Sopenharmony_ci				wrt_reg_word(&reg->hccr, HCCR_CLR_RISC_INT);
105862306a36Sopenharmony_ci				rd_reg_word(&reg->hccr);
105962306a36Sopenharmony_ci			}
106062306a36Sopenharmony_ci			udelay(5);
106162306a36Sopenharmony_ci		}
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_ci		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
106462306a36Sopenharmony_ci			rval = mb0 & MBS_MASK;
106562306a36Sopenharmony_ci			fw->risc_ram[cnt] = htons(mb2);
106662306a36Sopenharmony_ci		} else {
106762306a36Sopenharmony_ci			rval = QLA_FUNCTION_FAILED;
106862306a36Sopenharmony_ci		}
106962306a36Sopenharmony_ci	}
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_ci	if (rval == QLA_SUCCESS)
107262306a36Sopenharmony_ci		qla2xxx_copy_queues(ha, &fw->queue_dump[0]);
107362306a36Sopenharmony_ci
107462306a36Sopenharmony_ci	qla2xxx_dump_post_process(base_vha, rval);
107562306a36Sopenharmony_ci}
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_civoid
107862306a36Sopenharmony_ciqla24xx_fw_dump(scsi_qla_host_t *vha)
107962306a36Sopenharmony_ci{
108062306a36Sopenharmony_ci	int		rval;
108162306a36Sopenharmony_ci	uint32_t	cnt;
108262306a36Sopenharmony_ci	struct qla_hw_data *ha = vha->hw;
108362306a36Sopenharmony_ci	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
108462306a36Sopenharmony_ci	__le32 __iomem *dmp_reg;
108562306a36Sopenharmony_ci	__be32		*iter_reg;
108662306a36Sopenharmony_ci	__le16 __iomem *mbx_reg;
108762306a36Sopenharmony_ci	struct qla24xx_fw_dump *fw;
108862306a36Sopenharmony_ci	void		*nxt;
108962306a36Sopenharmony_ci	void		*nxt_chain;
109062306a36Sopenharmony_ci	__be32		*last_chain = NULL;
109162306a36Sopenharmony_ci	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
109262306a36Sopenharmony_ci
109362306a36Sopenharmony_ci	lockdep_assert_held(&ha->hardware_lock);
109462306a36Sopenharmony_ci
109562306a36Sopenharmony_ci	if (IS_P3P_TYPE(ha))
109662306a36Sopenharmony_ci		return;
109762306a36Sopenharmony_ci
109862306a36Sopenharmony_ci	ha->fw_dump_cap_flags = 0;
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_ci	if (!ha->fw_dump) {
110162306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd006,
110262306a36Sopenharmony_ci		    "No buffer available for dump.\n");
110362306a36Sopenharmony_ci		return;
110462306a36Sopenharmony_ci	}
110562306a36Sopenharmony_ci
110662306a36Sopenharmony_ci	if (ha->fw_dumped) {
110762306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd007,
110862306a36Sopenharmony_ci		    "Firmware has been previously dumped (%p) "
110962306a36Sopenharmony_ci		    "-- ignoring request.\n",
111062306a36Sopenharmony_ci		    ha->fw_dump);
111162306a36Sopenharmony_ci		return;
111262306a36Sopenharmony_ci	}
111362306a36Sopenharmony_ci	QLA_FW_STOPPED(ha);
111462306a36Sopenharmony_ci	fw = &ha->fw_dump->isp.isp24;
111562306a36Sopenharmony_ci	qla2xxx_prep_dump(ha, ha->fw_dump);
111662306a36Sopenharmony_ci
111762306a36Sopenharmony_ci	fw->host_status = htonl(rd_reg_dword(&reg->host_status));
111862306a36Sopenharmony_ci
111962306a36Sopenharmony_ci	/*
112062306a36Sopenharmony_ci	 * Pause RISC. No need to track timeout, as resetting the chip
112162306a36Sopenharmony_ci	 * is the right approach incase of pause timeout
112262306a36Sopenharmony_ci	 */
112362306a36Sopenharmony_ci	qla24xx_pause_risc(reg, ha);
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	/* Host interface registers. */
112662306a36Sopenharmony_ci	dmp_reg = &reg->flash_addr;
112762306a36Sopenharmony_ci	for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
112862306a36Sopenharmony_ci		fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg));
112962306a36Sopenharmony_ci
113062306a36Sopenharmony_ci	/* Disable interrupts. */
113162306a36Sopenharmony_ci	wrt_reg_dword(&reg->ictrl, 0);
113262306a36Sopenharmony_ci	rd_reg_dword(&reg->ictrl);
113362306a36Sopenharmony_ci
113462306a36Sopenharmony_ci	/* Shadow registers. */
113562306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x0F70);
113662306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_addr);
113762306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0000000);
113862306a36Sopenharmony_ci	fw->shadow_reg[0] = htonl(rd_reg_dword(&reg->iobase_sdata));
113962306a36Sopenharmony_ci
114062306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0100000);
114162306a36Sopenharmony_ci	fw->shadow_reg[1] = htonl(rd_reg_dword(&reg->iobase_sdata));
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0200000);
114462306a36Sopenharmony_ci	fw->shadow_reg[2] = htonl(rd_reg_dword(&reg->iobase_sdata));
114562306a36Sopenharmony_ci
114662306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0300000);
114762306a36Sopenharmony_ci	fw->shadow_reg[3] = htonl(rd_reg_dword(&reg->iobase_sdata));
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0400000);
115062306a36Sopenharmony_ci	fw->shadow_reg[4] = htonl(rd_reg_dword(&reg->iobase_sdata));
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0500000);
115362306a36Sopenharmony_ci	fw->shadow_reg[5] = htonl(rd_reg_dword(&reg->iobase_sdata));
115462306a36Sopenharmony_ci
115562306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0600000);
115662306a36Sopenharmony_ci	fw->shadow_reg[6] = htonl(rd_reg_dword(&reg->iobase_sdata));
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_ci	/* Mailbox registers. */
115962306a36Sopenharmony_ci	mbx_reg = &reg->mailbox0;
116062306a36Sopenharmony_ci	for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
116162306a36Sopenharmony_ci		fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg));
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_ci	/* Transfer sequence registers. */
116462306a36Sopenharmony_ci	iter_reg = fw->xseq_gp_reg;
116562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
116662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
116762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
116862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
116962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
117062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
117162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
117262306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBFE0, 16, fw->xseq_0_reg);
117562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
117662306a36Sopenharmony_ci
117762306a36Sopenharmony_ci	/* Receive sequence registers. */
117862306a36Sopenharmony_ci	iter_reg = fw->rseq_gp_reg;
117962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
118062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
118162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
118262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
118362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
118462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
118562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
118662306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFD0, 16, fw->rseq_0_reg);
118962306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
119062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_ci	/* Command DMA registers. */
119362306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
119462306a36Sopenharmony_ci
119562306a36Sopenharmony_ci	/* Queues. */
119662306a36Sopenharmony_ci	iter_reg = fw->req0_dma_reg;
119762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
119862306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
119962306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
120062306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_ci	iter_reg = fw->resp0_dma_reg;
120362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
120462306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
120562306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
120662306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
120762306a36Sopenharmony_ci
120862306a36Sopenharmony_ci	iter_reg = fw->req1_dma_reg;
120962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
121062306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
121162306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
121262306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
121362306a36Sopenharmony_ci
121462306a36Sopenharmony_ci	/* Transmit DMA registers. */
121562306a36Sopenharmony_ci	iter_reg = fw->xmt0_dma_reg;
121662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
121762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7610, 16, iter_reg);
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_ci	iter_reg = fw->xmt1_dma_reg;
122062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
122162306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7630, 16, iter_reg);
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci	iter_reg = fw->xmt2_dma_reg;
122462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
122562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7650, 16, iter_reg);
122662306a36Sopenharmony_ci
122762306a36Sopenharmony_ci	iter_reg = fw->xmt3_dma_reg;
122862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
122962306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7670, 16, iter_reg);
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_ci	iter_reg = fw->xmt4_dma_reg;
123262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
123362306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7690, 16, iter_reg);
123462306a36Sopenharmony_ci
123562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
123662306a36Sopenharmony_ci
123762306a36Sopenharmony_ci	/* Receive DMA registers. */
123862306a36Sopenharmony_ci	iter_reg = fw->rcvt0_data_dma_reg;
123962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
124062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7710, 16, iter_reg);
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_ci	iter_reg = fw->rcvt1_data_dma_reg;
124362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
124462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7730, 16, iter_reg);
124562306a36Sopenharmony_ci
124662306a36Sopenharmony_ci	/* RISC registers. */
124762306a36Sopenharmony_ci	iter_reg = fw->risc_gp_reg;
124862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
124962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
125062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
125162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
125262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
125362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
125462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
125562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
125662306a36Sopenharmony_ci
125762306a36Sopenharmony_ci	/* Local memory controller registers. */
125862306a36Sopenharmony_ci	iter_reg = fw->lmc_reg;
125962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
126062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
126162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
126262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
126362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
126462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
126562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x3060, 16, iter_reg);
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	/* Fibre Protocol Module registers. */
126862306a36Sopenharmony_ci	iter_reg = fw->fpm_hdw_reg;
126962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
127062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
127162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
127262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
127362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
127462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
127562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
127662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
127762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
127862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
127962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
128062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
128162306a36Sopenharmony_ci
128262306a36Sopenharmony_ci	/* Frame Buffer registers. */
128362306a36Sopenharmony_ci	iter_reg = fw->fb_hdw_reg;
128462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
128562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
128662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
128762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
128862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
128962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
129062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
129162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
129262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
129362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
129462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
129562306a36Sopenharmony_ci
129662306a36Sopenharmony_ci	rval = qla24xx_soft_reset(ha);
129762306a36Sopenharmony_ci	if (rval != QLA_SUCCESS)
129862306a36Sopenharmony_ci		goto qla24xx_fw_dump_failed_0;
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_ci	rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
130162306a36Sopenharmony_ci	    &nxt);
130262306a36Sopenharmony_ci	if (rval != QLA_SUCCESS)
130362306a36Sopenharmony_ci		goto qla24xx_fw_dump_failed_0;
130462306a36Sopenharmony_ci
130562306a36Sopenharmony_ci	nxt = qla2xxx_copy_queues(ha, nxt);
130662306a36Sopenharmony_ci
130762306a36Sopenharmony_ci	qla24xx_copy_eft(ha, nxt);
130862306a36Sopenharmony_ci
130962306a36Sopenharmony_ci	nxt_chain = (void *)ha->fw_dump + ha->chain_offset;
131062306a36Sopenharmony_ci	nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
131162306a36Sopenharmony_ci	if (last_chain) {
131262306a36Sopenharmony_ci		ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
131362306a36Sopenharmony_ci		*last_chain |= htonl(DUMP_CHAIN_LAST);
131462306a36Sopenharmony_ci	}
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_ci	/* Adjust valid length. */
131762306a36Sopenharmony_ci	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ciqla24xx_fw_dump_failed_0:
132062306a36Sopenharmony_ci	qla2xxx_dump_post_process(base_vha, rval);
132162306a36Sopenharmony_ci}
132262306a36Sopenharmony_ci
132362306a36Sopenharmony_civoid
132462306a36Sopenharmony_ciqla25xx_fw_dump(scsi_qla_host_t *vha)
132562306a36Sopenharmony_ci{
132662306a36Sopenharmony_ci	int		rval;
132762306a36Sopenharmony_ci	uint32_t	cnt;
132862306a36Sopenharmony_ci	struct qla_hw_data *ha = vha->hw;
132962306a36Sopenharmony_ci	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
133062306a36Sopenharmony_ci	__le32 __iomem *dmp_reg;
133162306a36Sopenharmony_ci	__be32		*iter_reg;
133262306a36Sopenharmony_ci	__le16 __iomem *mbx_reg;
133362306a36Sopenharmony_ci	struct qla25xx_fw_dump *fw;
133462306a36Sopenharmony_ci	void		*nxt, *nxt_chain;
133562306a36Sopenharmony_ci	__be32		*last_chain = NULL;
133662306a36Sopenharmony_ci	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
133762306a36Sopenharmony_ci
133862306a36Sopenharmony_ci	lockdep_assert_held(&ha->hardware_lock);
133962306a36Sopenharmony_ci
134062306a36Sopenharmony_ci	ha->fw_dump_cap_flags = 0;
134162306a36Sopenharmony_ci
134262306a36Sopenharmony_ci	if (!ha->fw_dump) {
134362306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd008,
134462306a36Sopenharmony_ci		    "No buffer available for dump.\n");
134562306a36Sopenharmony_ci		return;
134662306a36Sopenharmony_ci	}
134762306a36Sopenharmony_ci
134862306a36Sopenharmony_ci	if (ha->fw_dumped) {
134962306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd009,
135062306a36Sopenharmony_ci		    "Firmware has been previously dumped (%p) "
135162306a36Sopenharmony_ci		    "-- ignoring request.\n",
135262306a36Sopenharmony_ci		    ha->fw_dump);
135362306a36Sopenharmony_ci		return;
135462306a36Sopenharmony_ci	}
135562306a36Sopenharmony_ci	QLA_FW_STOPPED(ha);
135662306a36Sopenharmony_ci	fw = &ha->fw_dump->isp.isp25;
135762306a36Sopenharmony_ci	qla2xxx_prep_dump(ha, ha->fw_dump);
135862306a36Sopenharmony_ci	ha->fw_dump->version = htonl(2);
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ci	fw->host_status = htonl(rd_reg_dword(&reg->host_status));
136162306a36Sopenharmony_ci
136262306a36Sopenharmony_ci	/*
136362306a36Sopenharmony_ci	 * Pause RISC. No need to track timeout, as resetting the chip
136462306a36Sopenharmony_ci	 * is the right approach incase of pause timeout
136562306a36Sopenharmony_ci	 */
136662306a36Sopenharmony_ci	qla24xx_pause_risc(reg, ha);
136762306a36Sopenharmony_ci
136862306a36Sopenharmony_ci	/* Host/Risc registers. */
136962306a36Sopenharmony_ci	iter_reg = fw->host_risc_reg;
137062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
137162306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7010, 16, iter_reg);
137262306a36Sopenharmony_ci
137362306a36Sopenharmony_ci	/* PCIe registers. */
137462306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x7C00);
137562306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_addr);
137662306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_window, 0x01);
137762306a36Sopenharmony_ci	dmp_reg = &reg->iobase_c4;
137862306a36Sopenharmony_ci	fw->pcie_regs[0] = htonl(rd_reg_dword(dmp_reg));
137962306a36Sopenharmony_ci	dmp_reg++;
138062306a36Sopenharmony_ci	fw->pcie_regs[1] = htonl(rd_reg_dword(dmp_reg));
138162306a36Sopenharmony_ci	dmp_reg++;
138262306a36Sopenharmony_ci	fw->pcie_regs[2] = htonl(rd_reg_dword(dmp_reg));
138362306a36Sopenharmony_ci	fw->pcie_regs[3] = htonl(rd_reg_dword(&reg->iobase_window));
138462306a36Sopenharmony_ci
138562306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_window, 0x00);
138662306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_window);
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci	/* Host interface registers. */
138962306a36Sopenharmony_ci	dmp_reg = &reg->flash_addr;
139062306a36Sopenharmony_ci	for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
139162306a36Sopenharmony_ci		fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg));
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_ci	/* Disable interrupts. */
139462306a36Sopenharmony_ci	wrt_reg_dword(&reg->ictrl, 0);
139562306a36Sopenharmony_ci	rd_reg_dword(&reg->ictrl);
139662306a36Sopenharmony_ci
139762306a36Sopenharmony_ci	/* Shadow registers. */
139862306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x0F70);
139962306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_addr);
140062306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0000000);
140162306a36Sopenharmony_ci	fw->shadow_reg[0] = htonl(rd_reg_dword(&reg->iobase_sdata));
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0100000);
140462306a36Sopenharmony_ci	fw->shadow_reg[1] = htonl(rd_reg_dword(&reg->iobase_sdata));
140562306a36Sopenharmony_ci
140662306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0200000);
140762306a36Sopenharmony_ci	fw->shadow_reg[2] = htonl(rd_reg_dword(&reg->iobase_sdata));
140862306a36Sopenharmony_ci
140962306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0300000);
141062306a36Sopenharmony_ci	fw->shadow_reg[3] = htonl(rd_reg_dword(&reg->iobase_sdata));
141162306a36Sopenharmony_ci
141262306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0400000);
141362306a36Sopenharmony_ci	fw->shadow_reg[4] = htonl(rd_reg_dword(&reg->iobase_sdata));
141462306a36Sopenharmony_ci
141562306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0500000);
141662306a36Sopenharmony_ci	fw->shadow_reg[5] = htonl(rd_reg_dword(&reg->iobase_sdata));
141762306a36Sopenharmony_ci
141862306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0600000);
141962306a36Sopenharmony_ci	fw->shadow_reg[6] = htonl(rd_reg_dword(&reg->iobase_sdata));
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0700000);
142262306a36Sopenharmony_ci	fw->shadow_reg[7] = htonl(rd_reg_dword(&reg->iobase_sdata));
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0800000);
142562306a36Sopenharmony_ci	fw->shadow_reg[8] = htonl(rd_reg_dword(&reg->iobase_sdata));
142662306a36Sopenharmony_ci
142762306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0900000);
142862306a36Sopenharmony_ci	fw->shadow_reg[9] = htonl(rd_reg_dword(&reg->iobase_sdata));
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0A00000);
143162306a36Sopenharmony_ci	fw->shadow_reg[10] = htonl(rd_reg_dword(&reg->iobase_sdata));
143262306a36Sopenharmony_ci
143362306a36Sopenharmony_ci	/* RISC I/O register. */
143462306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x0010);
143562306a36Sopenharmony_ci	fw->risc_io_reg = htonl(rd_reg_dword(&reg->iobase_window));
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci	/* Mailbox registers. */
143862306a36Sopenharmony_ci	mbx_reg = &reg->mailbox0;
143962306a36Sopenharmony_ci	for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
144062306a36Sopenharmony_ci		fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg));
144162306a36Sopenharmony_ci
144262306a36Sopenharmony_ci	/* Transfer sequence registers. */
144362306a36Sopenharmony_ci	iter_reg = fw->xseq_gp_reg;
144462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
144562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
144662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
144762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
144862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
144962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
145062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
145162306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
145262306a36Sopenharmony_ci
145362306a36Sopenharmony_ci	iter_reg = fw->xseq_0_reg;
145462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
145562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
145662306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
145762306a36Sopenharmony_ci
145862306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
145962306a36Sopenharmony_ci
146062306a36Sopenharmony_ci	/* Receive sequence registers. */
146162306a36Sopenharmony_ci	iter_reg = fw->rseq_gp_reg;
146262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
146362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
146462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
146562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
146662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
146762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
146862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
146962306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
147062306a36Sopenharmony_ci
147162306a36Sopenharmony_ci	iter_reg = fw->rseq_0_reg;
147262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
147362306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
147462306a36Sopenharmony_ci
147562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
147662306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
147762306a36Sopenharmony_ci
147862306a36Sopenharmony_ci	/* Auxiliary sequence registers. */
147962306a36Sopenharmony_ci	iter_reg = fw->aseq_gp_reg;
148062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
148162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
148262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
148362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
148462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
148562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
148662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
148762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB070, 16, iter_reg);
148862306a36Sopenharmony_ci
148962306a36Sopenharmony_ci	iter_reg = fw->aseq_0_reg;
149062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
149162306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
149262306a36Sopenharmony_ci
149362306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
149462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
149562306a36Sopenharmony_ci
149662306a36Sopenharmony_ci	/* Command DMA registers. */
149762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
149862306a36Sopenharmony_ci
149962306a36Sopenharmony_ci	/* Queues. */
150062306a36Sopenharmony_ci	iter_reg = fw->req0_dma_reg;
150162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
150262306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
150362306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
150462306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
150562306a36Sopenharmony_ci
150662306a36Sopenharmony_ci	iter_reg = fw->resp0_dma_reg;
150762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
150862306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
150962306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
151062306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
151162306a36Sopenharmony_ci
151262306a36Sopenharmony_ci	iter_reg = fw->req1_dma_reg;
151362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
151462306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
151562306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
151662306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
151762306a36Sopenharmony_ci
151862306a36Sopenharmony_ci	/* Transmit DMA registers. */
151962306a36Sopenharmony_ci	iter_reg = fw->xmt0_dma_reg;
152062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
152162306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7610, 16, iter_reg);
152262306a36Sopenharmony_ci
152362306a36Sopenharmony_ci	iter_reg = fw->xmt1_dma_reg;
152462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
152562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7630, 16, iter_reg);
152662306a36Sopenharmony_ci
152762306a36Sopenharmony_ci	iter_reg = fw->xmt2_dma_reg;
152862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
152962306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7650, 16, iter_reg);
153062306a36Sopenharmony_ci
153162306a36Sopenharmony_ci	iter_reg = fw->xmt3_dma_reg;
153262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
153362306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7670, 16, iter_reg);
153462306a36Sopenharmony_ci
153562306a36Sopenharmony_ci	iter_reg = fw->xmt4_dma_reg;
153662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
153762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7690, 16, iter_reg);
153862306a36Sopenharmony_ci
153962306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
154062306a36Sopenharmony_ci
154162306a36Sopenharmony_ci	/* Receive DMA registers. */
154262306a36Sopenharmony_ci	iter_reg = fw->rcvt0_data_dma_reg;
154362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
154462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7710, 16, iter_reg);
154562306a36Sopenharmony_ci
154662306a36Sopenharmony_ci	iter_reg = fw->rcvt1_data_dma_reg;
154762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
154862306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7730, 16, iter_reg);
154962306a36Sopenharmony_ci
155062306a36Sopenharmony_ci	/* RISC registers. */
155162306a36Sopenharmony_ci	iter_reg = fw->risc_gp_reg;
155262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
155362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
155462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
155562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
155662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
155762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
155862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
155962306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
156062306a36Sopenharmony_ci
156162306a36Sopenharmony_ci	/* Local memory controller registers. */
156262306a36Sopenharmony_ci	iter_reg = fw->lmc_reg;
156362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
156462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
156562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
156662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
156762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
156862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
156962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
157062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x3070, 16, iter_reg);
157162306a36Sopenharmony_ci
157262306a36Sopenharmony_ci	/* Fibre Protocol Module registers. */
157362306a36Sopenharmony_ci	iter_reg = fw->fpm_hdw_reg;
157462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
157562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
157662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
157762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
157862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
157962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
158062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
158162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
158262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
158362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
158462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
158562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
158662306a36Sopenharmony_ci
158762306a36Sopenharmony_ci	/* Frame Buffer registers. */
158862306a36Sopenharmony_ci	iter_reg = fw->fb_hdw_reg;
158962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
159062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
159162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
159262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
159362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
159462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
159562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
159662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
159762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
159862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
159962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
160062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
160162306a36Sopenharmony_ci
160262306a36Sopenharmony_ci	/* Multi queue registers */
160362306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
160462306a36Sopenharmony_ci	    &last_chain);
160562306a36Sopenharmony_ci
160662306a36Sopenharmony_ci	rval = qla24xx_soft_reset(ha);
160762306a36Sopenharmony_ci	if (rval != QLA_SUCCESS)
160862306a36Sopenharmony_ci		goto qla25xx_fw_dump_failed_0;
160962306a36Sopenharmony_ci
161062306a36Sopenharmony_ci	rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
161162306a36Sopenharmony_ci	    &nxt);
161262306a36Sopenharmony_ci	if (rval != QLA_SUCCESS)
161362306a36Sopenharmony_ci		goto qla25xx_fw_dump_failed_0;
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_ci	nxt = qla2xxx_copy_queues(ha, nxt);
161662306a36Sopenharmony_ci
161762306a36Sopenharmony_ci	qla24xx_copy_eft(ha, nxt);
161862306a36Sopenharmony_ci
161962306a36Sopenharmony_ci	/* Chain entries -- started with MQ. */
162062306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
162162306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
162262306a36Sopenharmony_ci	nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
162362306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, &last_chain);
162462306a36Sopenharmony_ci	if (last_chain) {
162562306a36Sopenharmony_ci		ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
162662306a36Sopenharmony_ci		*last_chain |= htonl(DUMP_CHAIN_LAST);
162762306a36Sopenharmony_ci	}
162862306a36Sopenharmony_ci
162962306a36Sopenharmony_ci	/* Adjust valid length. */
163062306a36Sopenharmony_ci	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
163162306a36Sopenharmony_ci
163262306a36Sopenharmony_ciqla25xx_fw_dump_failed_0:
163362306a36Sopenharmony_ci	qla2xxx_dump_post_process(base_vha, rval);
163462306a36Sopenharmony_ci}
163562306a36Sopenharmony_ci
163662306a36Sopenharmony_civoid
163762306a36Sopenharmony_ciqla81xx_fw_dump(scsi_qla_host_t *vha)
163862306a36Sopenharmony_ci{
163962306a36Sopenharmony_ci	int		rval;
164062306a36Sopenharmony_ci	uint32_t	cnt;
164162306a36Sopenharmony_ci	struct qla_hw_data *ha = vha->hw;
164262306a36Sopenharmony_ci	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
164362306a36Sopenharmony_ci	__le32 __iomem *dmp_reg;
164462306a36Sopenharmony_ci	__be32		*iter_reg;
164562306a36Sopenharmony_ci	__le16 __iomem *mbx_reg;
164662306a36Sopenharmony_ci	struct qla81xx_fw_dump *fw;
164762306a36Sopenharmony_ci	void		*nxt, *nxt_chain;
164862306a36Sopenharmony_ci	__be32		*last_chain = NULL;
164962306a36Sopenharmony_ci	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
165062306a36Sopenharmony_ci
165162306a36Sopenharmony_ci	lockdep_assert_held(&ha->hardware_lock);
165262306a36Sopenharmony_ci
165362306a36Sopenharmony_ci	ha->fw_dump_cap_flags = 0;
165462306a36Sopenharmony_ci
165562306a36Sopenharmony_ci	if (!ha->fw_dump) {
165662306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd00a,
165762306a36Sopenharmony_ci		    "No buffer available for dump.\n");
165862306a36Sopenharmony_ci		return;
165962306a36Sopenharmony_ci	}
166062306a36Sopenharmony_ci
166162306a36Sopenharmony_ci	if (ha->fw_dumped) {
166262306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd00b,
166362306a36Sopenharmony_ci		    "Firmware has been previously dumped (%p) "
166462306a36Sopenharmony_ci		    "-- ignoring request.\n",
166562306a36Sopenharmony_ci		    ha->fw_dump);
166662306a36Sopenharmony_ci		return;
166762306a36Sopenharmony_ci	}
166862306a36Sopenharmony_ci	fw = &ha->fw_dump->isp.isp81;
166962306a36Sopenharmony_ci	qla2xxx_prep_dump(ha, ha->fw_dump);
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_ci	fw->host_status = htonl(rd_reg_dword(&reg->host_status));
167262306a36Sopenharmony_ci
167362306a36Sopenharmony_ci	/*
167462306a36Sopenharmony_ci	 * Pause RISC. No need to track timeout, as resetting the chip
167562306a36Sopenharmony_ci	 * is the right approach incase of pause timeout
167662306a36Sopenharmony_ci	 */
167762306a36Sopenharmony_ci	qla24xx_pause_risc(reg, ha);
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_ci	/* Host/Risc registers. */
168062306a36Sopenharmony_ci	iter_reg = fw->host_risc_reg;
168162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
168262306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7010, 16, iter_reg);
168362306a36Sopenharmony_ci
168462306a36Sopenharmony_ci	/* PCIe registers. */
168562306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x7C00);
168662306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_addr);
168762306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_window, 0x01);
168862306a36Sopenharmony_ci	dmp_reg = &reg->iobase_c4;
168962306a36Sopenharmony_ci	fw->pcie_regs[0] = htonl(rd_reg_dword(dmp_reg));
169062306a36Sopenharmony_ci	dmp_reg++;
169162306a36Sopenharmony_ci	fw->pcie_regs[1] = htonl(rd_reg_dword(dmp_reg));
169262306a36Sopenharmony_ci	dmp_reg++;
169362306a36Sopenharmony_ci	fw->pcie_regs[2] = htonl(rd_reg_dword(dmp_reg));
169462306a36Sopenharmony_ci	fw->pcie_regs[3] = htonl(rd_reg_dword(&reg->iobase_window));
169562306a36Sopenharmony_ci
169662306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_window, 0x00);
169762306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_window);
169862306a36Sopenharmony_ci
169962306a36Sopenharmony_ci	/* Host interface registers. */
170062306a36Sopenharmony_ci	dmp_reg = &reg->flash_addr;
170162306a36Sopenharmony_ci	for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
170262306a36Sopenharmony_ci		fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg));
170362306a36Sopenharmony_ci
170462306a36Sopenharmony_ci	/* Disable interrupts. */
170562306a36Sopenharmony_ci	wrt_reg_dword(&reg->ictrl, 0);
170662306a36Sopenharmony_ci	rd_reg_dword(&reg->ictrl);
170762306a36Sopenharmony_ci
170862306a36Sopenharmony_ci	/* Shadow registers. */
170962306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x0F70);
171062306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_addr);
171162306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0000000);
171262306a36Sopenharmony_ci	fw->shadow_reg[0] = htonl(rd_reg_dword(&reg->iobase_sdata));
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0100000);
171562306a36Sopenharmony_ci	fw->shadow_reg[1] = htonl(rd_reg_dword(&reg->iobase_sdata));
171662306a36Sopenharmony_ci
171762306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0200000);
171862306a36Sopenharmony_ci	fw->shadow_reg[2] = htonl(rd_reg_dword(&reg->iobase_sdata));
171962306a36Sopenharmony_ci
172062306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0300000);
172162306a36Sopenharmony_ci	fw->shadow_reg[3] = htonl(rd_reg_dword(&reg->iobase_sdata));
172262306a36Sopenharmony_ci
172362306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0400000);
172462306a36Sopenharmony_ci	fw->shadow_reg[4] = htonl(rd_reg_dword(&reg->iobase_sdata));
172562306a36Sopenharmony_ci
172662306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0500000);
172762306a36Sopenharmony_ci	fw->shadow_reg[5] = htonl(rd_reg_dword(&reg->iobase_sdata));
172862306a36Sopenharmony_ci
172962306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0600000);
173062306a36Sopenharmony_ci	fw->shadow_reg[6] = htonl(rd_reg_dword(&reg->iobase_sdata));
173162306a36Sopenharmony_ci
173262306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0700000);
173362306a36Sopenharmony_ci	fw->shadow_reg[7] = htonl(rd_reg_dword(&reg->iobase_sdata));
173462306a36Sopenharmony_ci
173562306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0800000);
173662306a36Sopenharmony_ci	fw->shadow_reg[8] = htonl(rd_reg_dword(&reg->iobase_sdata));
173762306a36Sopenharmony_ci
173862306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0900000);
173962306a36Sopenharmony_ci	fw->shadow_reg[9] = htonl(rd_reg_dword(&reg->iobase_sdata));
174062306a36Sopenharmony_ci
174162306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0A00000);
174262306a36Sopenharmony_ci	fw->shadow_reg[10] = htonl(rd_reg_dword(&reg->iobase_sdata));
174362306a36Sopenharmony_ci
174462306a36Sopenharmony_ci	/* RISC I/O register. */
174562306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x0010);
174662306a36Sopenharmony_ci	fw->risc_io_reg = htonl(rd_reg_dword(&reg->iobase_window));
174762306a36Sopenharmony_ci
174862306a36Sopenharmony_ci	/* Mailbox registers. */
174962306a36Sopenharmony_ci	mbx_reg = &reg->mailbox0;
175062306a36Sopenharmony_ci	for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
175162306a36Sopenharmony_ci		fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg));
175262306a36Sopenharmony_ci
175362306a36Sopenharmony_ci	/* Transfer sequence registers. */
175462306a36Sopenharmony_ci	iter_reg = fw->xseq_gp_reg;
175562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
175662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
175762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
175862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
175962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
176062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
176162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
176262306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
176362306a36Sopenharmony_ci
176462306a36Sopenharmony_ci	iter_reg = fw->xseq_0_reg;
176562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
176662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
176762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
176862306a36Sopenharmony_ci
176962306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
177062306a36Sopenharmony_ci
177162306a36Sopenharmony_ci	/* Receive sequence registers. */
177262306a36Sopenharmony_ci	iter_reg = fw->rseq_gp_reg;
177362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
177462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
177562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
177662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
177762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
177862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
177962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
178062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
178162306a36Sopenharmony_ci
178262306a36Sopenharmony_ci	iter_reg = fw->rseq_0_reg;
178362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
178462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
178562306a36Sopenharmony_ci
178662306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
178762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
178862306a36Sopenharmony_ci
178962306a36Sopenharmony_ci	/* Auxiliary sequence registers. */
179062306a36Sopenharmony_ci	iter_reg = fw->aseq_gp_reg;
179162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
179262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
179362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
179462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
179562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
179662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
179762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
179862306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB070, 16, iter_reg);
179962306a36Sopenharmony_ci
180062306a36Sopenharmony_ci	iter_reg = fw->aseq_0_reg;
180162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
180262306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
180362306a36Sopenharmony_ci
180462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
180562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
180662306a36Sopenharmony_ci
180762306a36Sopenharmony_ci	/* Command DMA registers. */
180862306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
180962306a36Sopenharmony_ci
181062306a36Sopenharmony_ci	/* Queues. */
181162306a36Sopenharmony_ci	iter_reg = fw->req0_dma_reg;
181262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
181362306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
181462306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
181562306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
181662306a36Sopenharmony_ci
181762306a36Sopenharmony_ci	iter_reg = fw->resp0_dma_reg;
181862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
181962306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
182062306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
182162306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
182262306a36Sopenharmony_ci
182362306a36Sopenharmony_ci	iter_reg = fw->req1_dma_reg;
182462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
182562306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
182662306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
182762306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
182862306a36Sopenharmony_ci
182962306a36Sopenharmony_ci	/* Transmit DMA registers. */
183062306a36Sopenharmony_ci	iter_reg = fw->xmt0_dma_reg;
183162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
183262306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7610, 16, iter_reg);
183362306a36Sopenharmony_ci
183462306a36Sopenharmony_ci	iter_reg = fw->xmt1_dma_reg;
183562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
183662306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7630, 16, iter_reg);
183762306a36Sopenharmony_ci
183862306a36Sopenharmony_ci	iter_reg = fw->xmt2_dma_reg;
183962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
184062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7650, 16, iter_reg);
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ci	iter_reg = fw->xmt3_dma_reg;
184362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
184462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7670, 16, iter_reg);
184562306a36Sopenharmony_ci
184662306a36Sopenharmony_ci	iter_reg = fw->xmt4_dma_reg;
184762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
184862306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7690, 16, iter_reg);
184962306a36Sopenharmony_ci
185062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
185162306a36Sopenharmony_ci
185262306a36Sopenharmony_ci	/* Receive DMA registers. */
185362306a36Sopenharmony_ci	iter_reg = fw->rcvt0_data_dma_reg;
185462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
185562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7710, 16, iter_reg);
185662306a36Sopenharmony_ci
185762306a36Sopenharmony_ci	iter_reg = fw->rcvt1_data_dma_reg;
185862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
185962306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7730, 16, iter_reg);
186062306a36Sopenharmony_ci
186162306a36Sopenharmony_ci	/* RISC registers. */
186262306a36Sopenharmony_ci	iter_reg = fw->risc_gp_reg;
186362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
186462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
186562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
186662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
186762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
186862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
186962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
187062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
187162306a36Sopenharmony_ci
187262306a36Sopenharmony_ci	/* Local memory controller registers. */
187362306a36Sopenharmony_ci	iter_reg = fw->lmc_reg;
187462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
187562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
187662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
187762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
187862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
187962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
188062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
188162306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x3070, 16, iter_reg);
188262306a36Sopenharmony_ci
188362306a36Sopenharmony_ci	/* Fibre Protocol Module registers. */
188462306a36Sopenharmony_ci	iter_reg = fw->fpm_hdw_reg;
188562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
188662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
188762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
188862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
188962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
189062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
189162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
189262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
189362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
189462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
189562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
189662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
189762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
189862306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
189962306a36Sopenharmony_ci
190062306a36Sopenharmony_ci	/* Frame Buffer registers. */
190162306a36Sopenharmony_ci	iter_reg = fw->fb_hdw_reg;
190262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
190362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
190462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
190562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
190662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
190762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
190862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
190962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
191062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
191162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
191262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
191362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
191462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
191562306a36Sopenharmony_ci
191662306a36Sopenharmony_ci	/* Multi queue registers */
191762306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
191862306a36Sopenharmony_ci	    &last_chain);
191962306a36Sopenharmony_ci
192062306a36Sopenharmony_ci	rval = qla24xx_soft_reset(ha);
192162306a36Sopenharmony_ci	if (rval != QLA_SUCCESS)
192262306a36Sopenharmony_ci		goto qla81xx_fw_dump_failed_0;
192362306a36Sopenharmony_ci
192462306a36Sopenharmony_ci	rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
192562306a36Sopenharmony_ci	    &nxt);
192662306a36Sopenharmony_ci	if (rval != QLA_SUCCESS)
192762306a36Sopenharmony_ci		goto qla81xx_fw_dump_failed_0;
192862306a36Sopenharmony_ci
192962306a36Sopenharmony_ci	nxt = qla2xxx_copy_queues(ha, nxt);
193062306a36Sopenharmony_ci
193162306a36Sopenharmony_ci	qla24xx_copy_eft(ha, nxt);
193262306a36Sopenharmony_ci
193362306a36Sopenharmony_ci	/* Chain entries -- started with MQ. */
193462306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
193562306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
193662306a36Sopenharmony_ci	nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
193762306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, &last_chain);
193862306a36Sopenharmony_ci	nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, &last_chain);
193962306a36Sopenharmony_ci	if (last_chain) {
194062306a36Sopenharmony_ci		ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
194162306a36Sopenharmony_ci		*last_chain |= htonl(DUMP_CHAIN_LAST);
194262306a36Sopenharmony_ci	}
194362306a36Sopenharmony_ci
194462306a36Sopenharmony_ci	/* Adjust valid length. */
194562306a36Sopenharmony_ci	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
194662306a36Sopenharmony_ci
194762306a36Sopenharmony_ciqla81xx_fw_dump_failed_0:
194862306a36Sopenharmony_ci	qla2xxx_dump_post_process(base_vha, rval);
194962306a36Sopenharmony_ci}
195062306a36Sopenharmony_ci
195162306a36Sopenharmony_civoid
195262306a36Sopenharmony_ciqla83xx_fw_dump(scsi_qla_host_t *vha)
195362306a36Sopenharmony_ci{
195462306a36Sopenharmony_ci	int		rval;
195562306a36Sopenharmony_ci	uint32_t	cnt;
195662306a36Sopenharmony_ci	struct qla_hw_data *ha = vha->hw;
195762306a36Sopenharmony_ci	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
195862306a36Sopenharmony_ci	__le32 __iomem *dmp_reg;
195962306a36Sopenharmony_ci	__be32		*iter_reg;
196062306a36Sopenharmony_ci	__le16 __iomem *mbx_reg;
196162306a36Sopenharmony_ci	struct qla83xx_fw_dump *fw;
196262306a36Sopenharmony_ci	void		*nxt, *nxt_chain;
196362306a36Sopenharmony_ci	__be32		*last_chain = NULL;
196462306a36Sopenharmony_ci	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
196562306a36Sopenharmony_ci
196662306a36Sopenharmony_ci	lockdep_assert_held(&ha->hardware_lock);
196762306a36Sopenharmony_ci
196862306a36Sopenharmony_ci	ha->fw_dump_cap_flags = 0;
196962306a36Sopenharmony_ci
197062306a36Sopenharmony_ci	if (!ha->fw_dump) {
197162306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd00c,
197262306a36Sopenharmony_ci		    "No buffer available for dump!!!\n");
197362306a36Sopenharmony_ci		return;
197462306a36Sopenharmony_ci	}
197562306a36Sopenharmony_ci
197662306a36Sopenharmony_ci	if (ha->fw_dumped) {
197762306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd00d,
197862306a36Sopenharmony_ci		    "Firmware has been previously dumped (%p) -- ignoring "
197962306a36Sopenharmony_ci		    "request...\n", ha->fw_dump);
198062306a36Sopenharmony_ci		return;
198162306a36Sopenharmony_ci	}
198262306a36Sopenharmony_ci	QLA_FW_STOPPED(ha);
198362306a36Sopenharmony_ci	fw = &ha->fw_dump->isp.isp83;
198462306a36Sopenharmony_ci	qla2xxx_prep_dump(ha, ha->fw_dump);
198562306a36Sopenharmony_ci
198662306a36Sopenharmony_ci	fw->host_status = htonl(rd_reg_dword(&reg->host_status));
198762306a36Sopenharmony_ci
198862306a36Sopenharmony_ci	/*
198962306a36Sopenharmony_ci	 * Pause RISC. No need to track timeout, as resetting the chip
199062306a36Sopenharmony_ci	 * is the right approach incase of pause timeout
199162306a36Sopenharmony_ci	 */
199262306a36Sopenharmony_ci	qla24xx_pause_risc(reg, ha);
199362306a36Sopenharmony_ci
199462306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x6000);
199562306a36Sopenharmony_ci	dmp_reg = &reg->iobase_window;
199662306a36Sopenharmony_ci	rd_reg_dword(dmp_reg);
199762306a36Sopenharmony_ci	wrt_reg_dword(dmp_reg, 0);
199862306a36Sopenharmony_ci
199962306a36Sopenharmony_ci	dmp_reg = &reg->unused_4_1[0];
200062306a36Sopenharmony_ci	rd_reg_dword(dmp_reg);
200162306a36Sopenharmony_ci	wrt_reg_dword(dmp_reg, 0);
200262306a36Sopenharmony_ci
200362306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x6010);
200462306a36Sopenharmony_ci	dmp_reg = &reg->unused_4_1[2];
200562306a36Sopenharmony_ci	rd_reg_dword(dmp_reg);
200662306a36Sopenharmony_ci	wrt_reg_dword(dmp_reg, 0);
200762306a36Sopenharmony_ci
200862306a36Sopenharmony_ci	/* select PCR and disable ecc checking and correction */
200962306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x0F70);
201062306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_addr);
201162306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0x60000000);	/* write to F0h = PCR */
201262306a36Sopenharmony_ci
201362306a36Sopenharmony_ci	/* Host/Risc registers. */
201462306a36Sopenharmony_ci	iter_reg = fw->host_risc_reg;
201562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
201662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7010, 16, iter_reg);
201762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7040, 16, iter_reg);
201862306a36Sopenharmony_ci
201962306a36Sopenharmony_ci	/* PCIe registers. */
202062306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x7C00);
202162306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_addr);
202262306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_window, 0x01);
202362306a36Sopenharmony_ci	dmp_reg = &reg->iobase_c4;
202462306a36Sopenharmony_ci	fw->pcie_regs[0] = htonl(rd_reg_dword(dmp_reg));
202562306a36Sopenharmony_ci	dmp_reg++;
202662306a36Sopenharmony_ci	fw->pcie_regs[1] = htonl(rd_reg_dword(dmp_reg));
202762306a36Sopenharmony_ci	dmp_reg++;
202862306a36Sopenharmony_ci	fw->pcie_regs[2] = htonl(rd_reg_dword(dmp_reg));
202962306a36Sopenharmony_ci	fw->pcie_regs[3] = htonl(rd_reg_dword(&reg->iobase_window));
203062306a36Sopenharmony_ci
203162306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_window, 0x00);
203262306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_window);
203362306a36Sopenharmony_ci
203462306a36Sopenharmony_ci	/* Host interface registers. */
203562306a36Sopenharmony_ci	dmp_reg = &reg->flash_addr;
203662306a36Sopenharmony_ci	for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
203762306a36Sopenharmony_ci		fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg));
203862306a36Sopenharmony_ci
203962306a36Sopenharmony_ci	/* Disable interrupts. */
204062306a36Sopenharmony_ci	wrt_reg_dword(&reg->ictrl, 0);
204162306a36Sopenharmony_ci	rd_reg_dword(&reg->ictrl);
204262306a36Sopenharmony_ci
204362306a36Sopenharmony_ci	/* Shadow registers. */
204462306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x0F70);
204562306a36Sopenharmony_ci	rd_reg_dword(&reg->iobase_addr);
204662306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0000000);
204762306a36Sopenharmony_ci	fw->shadow_reg[0] = htonl(rd_reg_dword(&reg->iobase_sdata));
204862306a36Sopenharmony_ci
204962306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0100000);
205062306a36Sopenharmony_ci	fw->shadow_reg[1] = htonl(rd_reg_dword(&reg->iobase_sdata));
205162306a36Sopenharmony_ci
205262306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0200000);
205362306a36Sopenharmony_ci	fw->shadow_reg[2] = htonl(rd_reg_dword(&reg->iobase_sdata));
205462306a36Sopenharmony_ci
205562306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0300000);
205662306a36Sopenharmony_ci	fw->shadow_reg[3] = htonl(rd_reg_dword(&reg->iobase_sdata));
205762306a36Sopenharmony_ci
205862306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0400000);
205962306a36Sopenharmony_ci	fw->shadow_reg[4] = htonl(rd_reg_dword(&reg->iobase_sdata));
206062306a36Sopenharmony_ci
206162306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0500000);
206262306a36Sopenharmony_ci	fw->shadow_reg[5] = htonl(rd_reg_dword(&reg->iobase_sdata));
206362306a36Sopenharmony_ci
206462306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0600000);
206562306a36Sopenharmony_ci	fw->shadow_reg[6] = htonl(rd_reg_dword(&reg->iobase_sdata));
206662306a36Sopenharmony_ci
206762306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0700000);
206862306a36Sopenharmony_ci	fw->shadow_reg[7] = htonl(rd_reg_dword(&reg->iobase_sdata));
206962306a36Sopenharmony_ci
207062306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0800000);
207162306a36Sopenharmony_ci	fw->shadow_reg[8] = htonl(rd_reg_dword(&reg->iobase_sdata));
207262306a36Sopenharmony_ci
207362306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0900000);
207462306a36Sopenharmony_ci	fw->shadow_reg[9] = htonl(rd_reg_dword(&reg->iobase_sdata));
207562306a36Sopenharmony_ci
207662306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_select, 0xB0A00000);
207762306a36Sopenharmony_ci	fw->shadow_reg[10] = htonl(rd_reg_dword(&reg->iobase_sdata));
207862306a36Sopenharmony_ci
207962306a36Sopenharmony_ci	/* RISC I/O register. */
208062306a36Sopenharmony_ci	wrt_reg_dword(&reg->iobase_addr, 0x0010);
208162306a36Sopenharmony_ci	fw->risc_io_reg = htonl(rd_reg_dword(&reg->iobase_window));
208262306a36Sopenharmony_ci
208362306a36Sopenharmony_ci	/* Mailbox registers. */
208462306a36Sopenharmony_ci	mbx_reg = &reg->mailbox0;
208562306a36Sopenharmony_ci	for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
208662306a36Sopenharmony_ci		fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg));
208762306a36Sopenharmony_ci
208862306a36Sopenharmony_ci	/* Transfer sequence registers. */
208962306a36Sopenharmony_ci	iter_reg = fw->xseq_gp_reg;
209062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBE00, 16, iter_reg);
209162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBE10, 16, iter_reg);
209262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBE20, 16, iter_reg);
209362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBE30, 16, iter_reg);
209462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBE40, 16, iter_reg);
209562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBE50, 16, iter_reg);
209662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBE60, 16, iter_reg);
209762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBE70, 16, iter_reg);
209862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
209962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
210062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
210162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
210262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
210362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
210462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
210562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
210662306a36Sopenharmony_ci
210762306a36Sopenharmony_ci	iter_reg = fw->xseq_0_reg;
210862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
210962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
211062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
211162306a36Sopenharmony_ci
211262306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
211362306a36Sopenharmony_ci
211462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xBEF0, 16, fw->xseq_2_reg);
211562306a36Sopenharmony_ci
211662306a36Sopenharmony_ci	/* Receive sequence registers. */
211762306a36Sopenharmony_ci	iter_reg = fw->rseq_gp_reg;
211862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFE00, 16, iter_reg);
211962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFE10, 16, iter_reg);
212062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFE20, 16, iter_reg);
212162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFE30, 16, iter_reg);
212262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFE40, 16, iter_reg);
212362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFE50, 16, iter_reg);
212462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFE60, 16, iter_reg);
212562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFE70, 16, iter_reg);
212662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
212762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
212862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
212962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
213062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
213162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
213262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
213362306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
213462306a36Sopenharmony_ci
213562306a36Sopenharmony_ci	iter_reg = fw->rseq_0_reg;
213662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
213762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
213862306a36Sopenharmony_ci
213962306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
214062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
214162306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xFEF0, 16, fw->rseq_3_reg);
214262306a36Sopenharmony_ci
214362306a36Sopenharmony_ci	/* Auxiliary sequence registers. */
214462306a36Sopenharmony_ci	iter_reg = fw->aseq_gp_reg;
214562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
214662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
214762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
214862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
214962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
215062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
215162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
215262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB070, 16, iter_reg);
215362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB100, 16, iter_reg);
215462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB110, 16, iter_reg);
215562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB120, 16, iter_reg);
215662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB130, 16, iter_reg);
215762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB140, 16, iter_reg);
215862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB150, 16, iter_reg);
215962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB160, 16, iter_reg);
216062306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB170, 16, iter_reg);
216162306a36Sopenharmony_ci
216262306a36Sopenharmony_ci	iter_reg = fw->aseq_0_reg;
216362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
216462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
216562306a36Sopenharmony_ci
216662306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
216762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
216862306a36Sopenharmony_ci	qla24xx_read_window(reg, 0xB1F0, 16, fw->aseq_3_reg);
216962306a36Sopenharmony_ci
217062306a36Sopenharmony_ci	/* Command DMA registers. */
217162306a36Sopenharmony_ci	iter_reg = fw->cmd_dma_reg;
217262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7100, 16, iter_reg);
217362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7120, 16, iter_reg);
217462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7130, 16, iter_reg);
217562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x71F0, 16, iter_reg);
217662306a36Sopenharmony_ci
217762306a36Sopenharmony_ci	/* Queues. */
217862306a36Sopenharmony_ci	iter_reg = fw->req0_dma_reg;
217962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
218062306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
218162306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
218262306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
218362306a36Sopenharmony_ci
218462306a36Sopenharmony_ci	iter_reg = fw->resp0_dma_reg;
218562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
218662306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
218762306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
218862306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
218962306a36Sopenharmony_ci
219062306a36Sopenharmony_ci	iter_reg = fw->req1_dma_reg;
219162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
219262306a36Sopenharmony_ci	dmp_reg = &reg->iobase_q;
219362306a36Sopenharmony_ci	for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
219462306a36Sopenharmony_ci		*iter_reg++ = htonl(rd_reg_dword(dmp_reg));
219562306a36Sopenharmony_ci
219662306a36Sopenharmony_ci	/* Transmit DMA registers. */
219762306a36Sopenharmony_ci	iter_reg = fw->xmt0_dma_reg;
219862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
219962306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7610, 16, iter_reg);
220062306a36Sopenharmony_ci
220162306a36Sopenharmony_ci	iter_reg = fw->xmt1_dma_reg;
220262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
220362306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7630, 16, iter_reg);
220462306a36Sopenharmony_ci
220562306a36Sopenharmony_ci	iter_reg = fw->xmt2_dma_reg;
220662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
220762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7650, 16, iter_reg);
220862306a36Sopenharmony_ci
220962306a36Sopenharmony_ci	iter_reg = fw->xmt3_dma_reg;
221062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
221162306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7670, 16, iter_reg);
221262306a36Sopenharmony_ci
221362306a36Sopenharmony_ci	iter_reg = fw->xmt4_dma_reg;
221462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
221562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7690, 16, iter_reg);
221662306a36Sopenharmony_ci
221762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
221862306a36Sopenharmony_ci
221962306a36Sopenharmony_ci	/* Receive DMA registers. */
222062306a36Sopenharmony_ci	iter_reg = fw->rcvt0_data_dma_reg;
222162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
222262306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7710, 16, iter_reg);
222362306a36Sopenharmony_ci
222462306a36Sopenharmony_ci	iter_reg = fw->rcvt1_data_dma_reg;
222562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
222662306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7730, 16, iter_reg);
222762306a36Sopenharmony_ci
222862306a36Sopenharmony_ci	/* RISC registers. */
222962306a36Sopenharmony_ci	iter_reg = fw->risc_gp_reg;
223062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
223162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
223262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
223362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
223462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
223562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
223662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
223762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
223862306a36Sopenharmony_ci
223962306a36Sopenharmony_ci	/* Local memory controller registers. */
224062306a36Sopenharmony_ci	iter_reg = fw->lmc_reg;
224162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
224262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
224362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
224462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
224562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
224662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
224762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
224862306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x3070, 16, iter_reg);
224962306a36Sopenharmony_ci
225062306a36Sopenharmony_ci	/* Fibre Protocol Module registers. */
225162306a36Sopenharmony_ci	iter_reg = fw->fpm_hdw_reg;
225262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
225362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
225462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
225562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
225662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
225762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
225862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
225962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
226062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
226162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
226262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
226362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
226462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
226562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
226662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x40E0, 16, iter_reg);
226762306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x40F0, 16, iter_reg);
226862306a36Sopenharmony_ci
226962306a36Sopenharmony_ci	/* RQ0 Array registers. */
227062306a36Sopenharmony_ci	iter_reg = fw->rq0_array_reg;
227162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5C00, 16, iter_reg);
227262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5C10, 16, iter_reg);
227362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5C20, 16, iter_reg);
227462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5C30, 16, iter_reg);
227562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5C40, 16, iter_reg);
227662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5C50, 16, iter_reg);
227762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5C60, 16, iter_reg);
227862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5C70, 16, iter_reg);
227962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5C80, 16, iter_reg);
228062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5C90, 16, iter_reg);
228162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5CA0, 16, iter_reg);
228262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5CB0, 16, iter_reg);
228362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5CC0, 16, iter_reg);
228462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5CD0, 16, iter_reg);
228562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5CE0, 16, iter_reg);
228662306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x5CF0, 16, iter_reg);
228762306a36Sopenharmony_ci
228862306a36Sopenharmony_ci	/* RQ1 Array registers. */
228962306a36Sopenharmony_ci	iter_reg = fw->rq1_array_reg;
229062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5D00, 16, iter_reg);
229162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5D10, 16, iter_reg);
229262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5D20, 16, iter_reg);
229362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5D30, 16, iter_reg);
229462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5D40, 16, iter_reg);
229562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5D50, 16, iter_reg);
229662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5D60, 16, iter_reg);
229762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5D70, 16, iter_reg);
229862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5D80, 16, iter_reg);
229962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5D90, 16, iter_reg);
230062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5DA0, 16, iter_reg);
230162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5DB0, 16, iter_reg);
230262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5DC0, 16, iter_reg);
230362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5DD0, 16, iter_reg);
230462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5DE0, 16, iter_reg);
230562306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x5DF0, 16, iter_reg);
230662306a36Sopenharmony_ci
230762306a36Sopenharmony_ci	/* RP0 Array registers. */
230862306a36Sopenharmony_ci	iter_reg = fw->rp0_array_reg;
230962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5E00, 16, iter_reg);
231062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5E10, 16, iter_reg);
231162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5E20, 16, iter_reg);
231262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5E30, 16, iter_reg);
231362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5E40, 16, iter_reg);
231462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5E50, 16, iter_reg);
231562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5E60, 16, iter_reg);
231662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5E70, 16, iter_reg);
231762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5E80, 16, iter_reg);
231862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5E90, 16, iter_reg);
231962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5EA0, 16, iter_reg);
232062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5EB0, 16, iter_reg);
232162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5EC0, 16, iter_reg);
232262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5ED0, 16, iter_reg);
232362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5EE0, 16, iter_reg);
232462306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x5EF0, 16, iter_reg);
232562306a36Sopenharmony_ci
232662306a36Sopenharmony_ci	/* RP1 Array registers. */
232762306a36Sopenharmony_ci	iter_reg = fw->rp1_array_reg;
232862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5F00, 16, iter_reg);
232962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5F10, 16, iter_reg);
233062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5F20, 16, iter_reg);
233162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5F30, 16, iter_reg);
233262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5F40, 16, iter_reg);
233362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5F50, 16, iter_reg);
233462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5F60, 16, iter_reg);
233562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5F70, 16, iter_reg);
233662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5F80, 16, iter_reg);
233762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5F90, 16, iter_reg);
233862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5FA0, 16, iter_reg);
233962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5FB0, 16, iter_reg);
234062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5FC0, 16, iter_reg);
234162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5FD0, 16, iter_reg);
234262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x5FE0, 16, iter_reg);
234362306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x5FF0, 16, iter_reg);
234462306a36Sopenharmony_ci
234562306a36Sopenharmony_ci	iter_reg = fw->at0_array_reg;
234662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7080, 16, iter_reg);
234762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x7090, 16, iter_reg);
234862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x70A0, 16, iter_reg);
234962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x70B0, 16, iter_reg);
235062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x70C0, 16, iter_reg);
235162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x70D0, 16, iter_reg);
235262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x70E0, 16, iter_reg);
235362306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x70F0, 16, iter_reg);
235462306a36Sopenharmony_ci
235562306a36Sopenharmony_ci	/* I/O Queue Control registers. */
235662306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x7800, 16, fw->queue_control_reg);
235762306a36Sopenharmony_ci
235862306a36Sopenharmony_ci	/* Frame Buffer registers. */
235962306a36Sopenharmony_ci	iter_reg = fw->fb_hdw_reg;
236062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
236162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
236262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
236362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
236462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
236562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6060, 16, iter_reg);
236662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6070, 16, iter_reg);
236762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
236862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
236962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
237062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
237162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
237262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
237362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
237462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6530, 16, iter_reg);
237562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6540, 16, iter_reg);
237662306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6550, 16, iter_reg);
237762306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6560, 16, iter_reg);
237862306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6570, 16, iter_reg);
237962306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6580, 16, iter_reg);
238062306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x6590, 16, iter_reg);
238162306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x65A0, 16, iter_reg);
238262306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x65B0, 16, iter_reg);
238362306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x65C0, 16, iter_reg);
238462306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x65D0, 16, iter_reg);
238562306a36Sopenharmony_ci	iter_reg = qla24xx_read_window(reg, 0x65E0, 16, iter_reg);
238662306a36Sopenharmony_ci	qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
238762306a36Sopenharmony_ci
238862306a36Sopenharmony_ci	/* Multi queue registers */
238962306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
239062306a36Sopenharmony_ci	    &last_chain);
239162306a36Sopenharmony_ci
239262306a36Sopenharmony_ci	rval = qla24xx_soft_reset(ha);
239362306a36Sopenharmony_ci	if (rval != QLA_SUCCESS) {
239462306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd00e,
239562306a36Sopenharmony_ci		    "SOFT RESET FAILED, forcing continuation of dump!!!\n");
239662306a36Sopenharmony_ci		rval = QLA_SUCCESS;
239762306a36Sopenharmony_ci
239862306a36Sopenharmony_ci		ql_log(ql_log_warn, vha, 0xd00f, "try a bigger hammer!!!\n");
239962306a36Sopenharmony_ci
240062306a36Sopenharmony_ci		wrt_reg_dword(&reg->hccr, HCCRX_SET_RISC_RESET);
240162306a36Sopenharmony_ci		rd_reg_dword(&reg->hccr);
240262306a36Sopenharmony_ci
240362306a36Sopenharmony_ci		wrt_reg_dword(&reg->hccr, HCCRX_REL_RISC_PAUSE);
240462306a36Sopenharmony_ci		rd_reg_dword(&reg->hccr);
240562306a36Sopenharmony_ci
240662306a36Sopenharmony_ci		wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_RESET);
240762306a36Sopenharmony_ci		rd_reg_dword(&reg->hccr);
240862306a36Sopenharmony_ci
240962306a36Sopenharmony_ci		for (cnt = 30000; cnt && (rd_reg_word(&reg->mailbox0)); cnt--)
241062306a36Sopenharmony_ci			udelay(5);
241162306a36Sopenharmony_ci
241262306a36Sopenharmony_ci		if (!cnt) {
241362306a36Sopenharmony_ci			nxt = fw->code_ram;
241462306a36Sopenharmony_ci			nxt += sizeof(fw->code_ram);
241562306a36Sopenharmony_ci			nxt += (ha->fw_memory_size - 0x100000 + 1);
241662306a36Sopenharmony_ci			goto copy_queue;
241762306a36Sopenharmony_ci		} else {
241862306a36Sopenharmony_ci			set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
241962306a36Sopenharmony_ci			ql_log(ql_log_warn, vha, 0xd010,
242062306a36Sopenharmony_ci			    "bigger hammer success?\n");
242162306a36Sopenharmony_ci		}
242262306a36Sopenharmony_ci	}
242362306a36Sopenharmony_ci
242462306a36Sopenharmony_ci	rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
242562306a36Sopenharmony_ci	    &nxt);
242662306a36Sopenharmony_ci	if (rval != QLA_SUCCESS)
242762306a36Sopenharmony_ci		goto qla83xx_fw_dump_failed_0;
242862306a36Sopenharmony_ci
242962306a36Sopenharmony_cicopy_queue:
243062306a36Sopenharmony_ci	nxt = qla2xxx_copy_queues(ha, nxt);
243162306a36Sopenharmony_ci
243262306a36Sopenharmony_ci	qla24xx_copy_eft(ha, nxt);
243362306a36Sopenharmony_ci
243462306a36Sopenharmony_ci	/* Chain entries -- started with MQ. */
243562306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
243662306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
243762306a36Sopenharmony_ci	nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
243862306a36Sopenharmony_ci	nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, &last_chain);
243962306a36Sopenharmony_ci	nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, &last_chain);
244062306a36Sopenharmony_ci	if (last_chain) {
244162306a36Sopenharmony_ci		ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
244262306a36Sopenharmony_ci		*last_chain |= htonl(DUMP_CHAIN_LAST);
244362306a36Sopenharmony_ci	}
244462306a36Sopenharmony_ci
244562306a36Sopenharmony_ci	/* Adjust valid length. */
244662306a36Sopenharmony_ci	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
244762306a36Sopenharmony_ci
244862306a36Sopenharmony_ciqla83xx_fw_dump_failed_0:
244962306a36Sopenharmony_ci	qla2xxx_dump_post_process(base_vha, rval);
245062306a36Sopenharmony_ci}
245162306a36Sopenharmony_ci
245262306a36Sopenharmony_ci/****************************************************************************/
245362306a36Sopenharmony_ci/*                         Driver Debug Functions.                          */
245462306a36Sopenharmony_ci/****************************************************************************/
245562306a36Sopenharmony_ci
245662306a36Sopenharmony_ci/* Write the debug message prefix into @pbuf. */
245762306a36Sopenharmony_cistatic void ql_dbg_prefix(char *pbuf, int pbuf_size, struct pci_dev *pdev,
245862306a36Sopenharmony_ci			  const scsi_qla_host_t *vha, uint msg_id)
245962306a36Sopenharmony_ci{
246062306a36Sopenharmony_ci	if (vha) {
246162306a36Sopenharmony_ci		const struct pci_dev *pdev = vha->hw->pdev;
246262306a36Sopenharmony_ci
246362306a36Sopenharmony_ci		/* <module-name> [<dev-name>]-<msg-id>:<host>: */
246462306a36Sopenharmony_ci		snprintf(pbuf, pbuf_size, "%s [%s]-%04x:%lu: ", QL_MSGHDR,
246562306a36Sopenharmony_ci			 dev_name(&(pdev->dev)), msg_id, vha->host_no);
246662306a36Sopenharmony_ci	} else if (pdev) {
246762306a36Sopenharmony_ci		snprintf(pbuf, pbuf_size, "%s [%s]-%04x: : ", QL_MSGHDR,
246862306a36Sopenharmony_ci			 dev_name(&pdev->dev), msg_id);
246962306a36Sopenharmony_ci	} else {
247062306a36Sopenharmony_ci		/* <module-name> [<dev-name>]-<msg-id>: : */
247162306a36Sopenharmony_ci		snprintf(pbuf, pbuf_size, "%s [%s]-%04x: : ", QL_MSGHDR,
247262306a36Sopenharmony_ci			 "0000:00:00.0", msg_id);
247362306a36Sopenharmony_ci	}
247462306a36Sopenharmony_ci}
247562306a36Sopenharmony_ci
247662306a36Sopenharmony_ci/*
247762306a36Sopenharmony_ci * This function is for formatting and logging debug information.
247862306a36Sopenharmony_ci * It is to be used when vha is available. It formats the message
247962306a36Sopenharmony_ci * and logs it to the messages file.
248062306a36Sopenharmony_ci * parameters:
248162306a36Sopenharmony_ci * level: The level of the debug messages to be printed.
248262306a36Sopenharmony_ci *        If ql2xextended_error_logging value is correctly set,
248362306a36Sopenharmony_ci *        this message will appear in the messages file.
248462306a36Sopenharmony_ci * vha:   Pointer to the scsi_qla_host_t.
248562306a36Sopenharmony_ci * id:    This is a unique identifier for the level. It identifies the
248662306a36Sopenharmony_ci *        part of the code from where the message originated.
248762306a36Sopenharmony_ci * msg:   The message to be displayed.
248862306a36Sopenharmony_ci */
248962306a36Sopenharmony_civoid
249062306a36Sopenharmony_ciql_dbg(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...)
249162306a36Sopenharmony_ci{
249262306a36Sopenharmony_ci	va_list va;
249362306a36Sopenharmony_ci	struct va_format vaf;
249462306a36Sopenharmony_ci	char pbuf[64];
249562306a36Sopenharmony_ci
249662306a36Sopenharmony_ci	ql_ktrace(1, level, pbuf, NULL, vha, id, fmt);
249762306a36Sopenharmony_ci
249862306a36Sopenharmony_ci	if (!ql_mask_match(level))
249962306a36Sopenharmony_ci		return;
250062306a36Sopenharmony_ci
250162306a36Sopenharmony_ci	if (!pbuf[0]) /* set by ql_ktrace */
250262306a36Sopenharmony_ci		ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, vha, id);
250362306a36Sopenharmony_ci
250462306a36Sopenharmony_ci	va_start(va, fmt);
250562306a36Sopenharmony_ci
250662306a36Sopenharmony_ci	vaf.fmt = fmt;
250762306a36Sopenharmony_ci	vaf.va = &va;
250862306a36Sopenharmony_ci
250962306a36Sopenharmony_ci	pr_warn("%s%pV", pbuf, &vaf);
251062306a36Sopenharmony_ci
251162306a36Sopenharmony_ci	va_end(va);
251262306a36Sopenharmony_ci
251362306a36Sopenharmony_ci}
251462306a36Sopenharmony_ci
251562306a36Sopenharmony_ci/*
251662306a36Sopenharmony_ci * This function is for formatting and logging debug information.
251762306a36Sopenharmony_ci * It is to be used when vha is not available and pci is available,
251862306a36Sopenharmony_ci * i.e., before host allocation. It formats the message and logs it
251962306a36Sopenharmony_ci * to the messages file.
252062306a36Sopenharmony_ci * parameters:
252162306a36Sopenharmony_ci * level: The level of the debug messages to be printed.
252262306a36Sopenharmony_ci *        If ql2xextended_error_logging value is correctly set,
252362306a36Sopenharmony_ci *        this message will appear in the messages file.
252462306a36Sopenharmony_ci * pdev:  Pointer to the struct pci_dev.
252562306a36Sopenharmony_ci * id:    This is a unique id for the level. It identifies the part
252662306a36Sopenharmony_ci *        of the code from where the message originated.
252762306a36Sopenharmony_ci * msg:   The message to be displayed.
252862306a36Sopenharmony_ci */
252962306a36Sopenharmony_civoid
253062306a36Sopenharmony_ciql_dbg_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...)
253162306a36Sopenharmony_ci{
253262306a36Sopenharmony_ci	va_list va;
253362306a36Sopenharmony_ci	struct va_format vaf;
253462306a36Sopenharmony_ci	char pbuf[128];
253562306a36Sopenharmony_ci
253662306a36Sopenharmony_ci	if (pdev == NULL)
253762306a36Sopenharmony_ci		return;
253862306a36Sopenharmony_ci
253962306a36Sopenharmony_ci	ql_ktrace(1, level, pbuf, pdev, NULL, id, fmt);
254062306a36Sopenharmony_ci
254162306a36Sopenharmony_ci	if (!ql_mask_match(level))
254262306a36Sopenharmony_ci		return;
254362306a36Sopenharmony_ci
254462306a36Sopenharmony_ci	va_start(va, fmt);
254562306a36Sopenharmony_ci
254662306a36Sopenharmony_ci	vaf.fmt = fmt;
254762306a36Sopenharmony_ci	vaf.va = &va;
254862306a36Sopenharmony_ci
254962306a36Sopenharmony_ci	if (!pbuf[0]) /* set by ql_ktrace */
255062306a36Sopenharmony_ci		ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), pdev, NULL,
255162306a36Sopenharmony_ci			      id + ql_dbg_offset);
255262306a36Sopenharmony_ci	pr_warn("%s%pV", pbuf, &vaf);
255362306a36Sopenharmony_ci
255462306a36Sopenharmony_ci	va_end(va);
255562306a36Sopenharmony_ci}
255662306a36Sopenharmony_ci
255762306a36Sopenharmony_ci/*
255862306a36Sopenharmony_ci * This function is for formatting and logging log messages.
255962306a36Sopenharmony_ci * It is to be used when vha is available. It formats the message
256062306a36Sopenharmony_ci * and logs it to the messages file. All the messages will be logged
256162306a36Sopenharmony_ci * irrespective of value of ql2xextended_error_logging.
256262306a36Sopenharmony_ci * parameters:
256362306a36Sopenharmony_ci * level: The level of the log messages to be printed in the
256462306a36Sopenharmony_ci *        messages file.
256562306a36Sopenharmony_ci * vha:   Pointer to the scsi_qla_host_t
256662306a36Sopenharmony_ci * id:    This is a unique id for the level. It identifies the
256762306a36Sopenharmony_ci *        part of the code from where the message originated.
256862306a36Sopenharmony_ci * msg:   The message to be displayed.
256962306a36Sopenharmony_ci */
257062306a36Sopenharmony_civoid
257162306a36Sopenharmony_ciql_log(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...)
257262306a36Sopenharmony_ci{
257362306a36Sopenharmony_ci	va_list va;
257462306a36Sopenharmony_ci	struct va_format vaf;
257562306a36Sopenharmony_ci	char pbuf[128];
257662306a36Sopenharmony_ci
257762306a36Sopenharmony_ci	if (level > ql_errlev)
257862306a36Sopenharmony_ci		return;
257962306a36Sopenharmony_ci
258062306a36Sopenharmony_ci	ql_ktrace(0, level, pbuf, NULL, vha, id, fmt);
258162306a36Sopenharmony_ci
258262306a36Sopenharmony_ci	if (!pbuf[0]) /* set by ql_ktrace */
258362306a36Sopenharmony_ci		ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, vha, id);
258462306a36Sopenharmony_ci
258562306a36Sopenharmony_ci	va_start(va, fmt);
258662306a36Sopenharmony_ci
258762306a36Sopenharmony_ci	vaf.fmt = fmt;
258862306a36Sopenharmony_ci	vaf.va = &va;
258962306a36Sopenharmony_ci
259062306a36Sopenharmony_ci	switch (level) {
259162306a36Sopenharmony_ci	case ql_log_fatal: /* FATAL LOG */
259262306a36Sopenharmony_ci		pr_crit("%s%pV", pbuf, &vaf);
259362306a36Sopenharmony_ci		break;
259462306a36Sopenharmony_ci	case ql_log_warn:
259562306a36Sopenharmony_ci		pr_err("%s%pV", pbuf, &vaf);
259662306a36Sopenharmony_ci		break;
259762306a36Sopenharmony_ci	case ql_log_info:
259862306a36Sopenharmony_ci		pr_warn("%s%pV", pbuf, &vaf);
259962306a36Sopenharmony_ci		break;
260062306a36Sopenharmony_ci	default:
260162306a36Sopenharmony_ci		pr_info("%s%pV", pbuf, &vaf);
260262306a36Sopenharmony_ci		break;
260362306a36Sopenharmony_ci	}
260462306a36Sopenharmony_ci
260562306a36Sopenharmony_ci	va_end(va);
260662306a36Sopenharmony_ci}
260762306a36Sopenharmony_ci
260862306a36Sopenharmony_ci/*
260962306a36Sopenharmony_ci * This function is for formatting and logging log messages.
261062306a36Sopenharmony_ci * It is to be used when vha is not available and pci is available,
261162306a36Sopenharmony_ci * i.e., before host allocation. It formats the message and logs
261262306a36Sopenharmony_ci * it to the messages file. All the messages are logged irrespective
261362306a36Sopenharmony_ci * of the value of ql2xextended_error_logging.
261462306a36Sopenharmony_ci * parameters:
261562306a36Sopenharmony_ci * level: The level of the log messages to be printed in the
261662306a36Sopenharmony_ci *        messages file.
261762306a36Sopenharmony_ci * pdev:  Pointer to the struct pci_dev.
261862306a36Sopenharmony_ci * id:    This is a unique id for the level. It identifies the
261962306a36Sopenharmony_ci *        part of the code from where the message originated.
262062306a36Sopenharmony_ci * msg:   The message to be displayed.
262162306a36Sopenharmony_ci */
262262306a36Sopenharmony_civoid
262362306a36Sopenharmony_ciql_log_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...)
262462306a36Sopenharmony_ci{
262562306a36Sopenharmony_ci	va_list va;
262662306a36Sopenharmony_ci	struct va_format vaf;
262762306a36Sopenharmony_ci	char pbuf[128];
262862306a36Sopenharmony_ci
262962306a36Sopenharmony_ci	if (pdev == NULL)
263062306a36Sopenharmony_ci		return;
263162306a36Sopenharmony_ci	if (level > ql_errlev)
263262306a36Sopenharmony_ci		return;
263362306a36Sopenharmony_ci
263462306a36Sopenharmony_ci	ql_ktrace(0, level, pbuf, pdev, NULL, id, fmt);
263562306a36Sopenharmony_ci
263662306a36Sopenharmony_ci	if (!pbuf[0]) /* set by ql_ktrace */
263762306a36Sopenharmony_ci		ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), pdev, NULL, id);
263862306a36Sopenharmony_ci
263962306a36Sopenharmony_ci	va_start(va, fmt);
264062306a36Sopenharmony_ci
264162306a36Sopenharmony_ci	vaf.fmt = fmt;
264262306a36Sopenharmony_ci	vaf.va = &va;
264362306a36Sopenharmony_ci
264462306a36Sopenharmony_ci	switch (level) {
264562306a36Sopenharmony_ci	case ql_log_fatal: /* FATAL LOG */
264662306a36Sopenharmony_ci		pr_crit("%s%pV", pbuf, &vaf);
264762306a36Sopenharmony_ci		break;
264862306a36Sopenharmony_ci	case ql_log_warn:
264962306a36Sopenharmony_ci		pr_err("%s%pV", pbuf, &vaf);
265062306a36Sopenharmony_ci		break;
265162306a36Sopenharmony_ci	case ql_log_info:
265262306a36Sopenharmony_ci		pr_warn("%s%pV", pbuf, &vaf);
265362306a36Sopenharmony_ci		break;
265462306a36Sopenharmony_ci	default:
265562306a36Sopenharmony_ci		pr_info("%s%pV", pbuf, &vaf);
265662306a36Sopenharmony_ci		break;
265762306a36Sopenharmony_ci	}
265862306a36Sopenharmony_ci
265962306a36Sopenharmony_ci	va_end(va);
266062306a36Sopenharmony_ci}
266162306a36Sopenharmony_ci
266262306a36Sopenharmony_civoid
266362306a36Sopenharmony_ciql_dump_regs(uint level, scsi_qla_host_t *vha, uint id)
266462306a36Sopenharmony_ci{
266562306a36Sopenharmony_ci	int i;
266662306a36Sopenharmony_ci	struct qla_hw_data *ha = vha->hw;
266762306a36Sopenharmony_ci	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
266862306a36Sopenharmony_ci	struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
266962306a36Sopenharmony_ci	struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
267062306a36Sopenharmony_ci	__le16 __iomem *mbx_reg;
267162306a36Sopenharmony_ci
267262306a36Sopenharmony_ci	if (!ql_mask_match(level))
267362306a36Sopenharmony_ci		return;
267462306a36Sopenharmony_ci
267562306a36Sopenharmony_ci	if (IS_P3P_TYPE(ha))
267662306a36Sopenharmony_ci		mbx_reg = &reg82->mailbox_in[0];
267762306a36Sopenharmony_ci	else if (IS_FWI2_CAPABLE(ha))
267862306a36Sopenharmony_ci		mbx_reg = &reg24->mailbox0;
267962306a36Sopenharmony_ci	else
268062306a36Sopenharmony_ci		mbx_reg = MAILBOX_REG(ha, reg, 0);
268162306a36Sopenharmony_ci
268262306a36Sopenharmony_ci	ql_dbg(level, vha, id, "Mailbox registers:\n");
268362306a36Sopenharmony_ci	for (i = 0; i < 6; i++, mbx_reg++)
268462306a36Sopenharmony_ci		ql_dbg(level, vha, id,
268562306a36Sopenharmony_ci		    "mbox[%d] %#04x\n", i, rd_reg_word(mbx_reg));
268662306a36Sopenharmony_ci}
268762306a36Sopenharmony_ci
268862306a36Sopenharmony_civoid
268962306a36Sopenharmony_ciql_dump_buffer(uint level, scsi_qla_host_t *vha, uint id, const void *buf,
269062306a36Sopenharmony_ci	       uint size)
269162306a36Sopenharmony_ci{
269262306a36Sopenharmony_ci	uint cnt;
269362306a36Sopenharmony_ci
269462306a36Sopenharmony_ci	if (!ql_mask_match(level))
269562306a36Sopenharmony_ci		return;
269662306a36Sopenharmony_ci
269762306a36Sopenharmony_ci	ql_dbg(level, vha, id,
269862306a36Sopenharmony_ci	    "%-+5d  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\n", size);
269962306a36Sopenharmony_ci	ql_dbg(level, vha, id,
270062306a36Sopenharmony_ci	    "----- -----------------------------------------------\n");
270162306a36Sopenharmony_ci	for (cnt = 0; cnt < size; cnt += 16) {
270262306a36Sopenharmony_ci		ql_dbg(level, vha, id, "%04x: ", cnt);
270362306a36Sopenharmony_ci		print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1,
270462306a36Sopenharmony_ci			       buf + cnt, min(16U, size - cnt), false);
270562306a36Sopenharmony_ci	}
270662306a36Sopenharmony_ci}
270762306a36Sopenharmony_ci
270862306a36Sopenharmony_ci/*
270962306a36Sopenharmony_ci * This function is for formatting and logging log messages.
271062306a36Sopenharmony_ci * It is to be used when vha is available. It formats the message
271162306a36Sopenharmony_ci * and logs it to the messages file. All the messages will be logged
271262306a36Sopenharmony_ci * irrespective of value of ql2xextended_error_logging.
271362306a36Sopenharmony_ci * parameters:
271462306a36Sopenharmony_ci * level: The level of the log messages to be printed in the
271562306a36Sopenharmony_ci *        messages file.
271662306a36Sopenharmony_ci * vha:   Pointer to the scsi_qla_host_t
271762306a36Sopenharmony_ci * id:    This is a unique id for the level. It identifies the
271862306a36Sopenharmony_ci *        part of the code from where the message originated.
271962306a36Sopenharmony_ci * msg:   The message to be displayed.
272062306a36Sopenharmony_ci */
272162306a36Sopenharmony_civoid
272262306a36Sopenharmony_ciql_log_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
272362306a36Sopenharmony_ci    const char *fmt, ...)
272462306a36Sopenharmony_ci{
272562306a36Sopenharmony_ci	va_list va;
272662306a36Sopenharmony_ci	struct va_format vaf;
272762306a36Sopenharmony_ci	char pbuf[128];
272862306a36Sopenharmony_ci
272962306a36Sopenharmony_ci	if (level > ql_errlev)
273062306a36Sopenharmony_ci		return;
273162306a36Sopenharmony_ci
273262306a36Sopenharmony_ci	ql_ktrace(0, level, pbuf, NULL, qpair ? qpair->vha : NULL, id, fmt);
273362306a36Sopenharmony_ci
273462306a36Sopenharmony_ci	if (!pbuf[0]) /* set by ql_ktrace */
273562306a36Sopenharmony_ci		ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL,
273662306a36Sopenharmony_ci			      qpair ? qpair->vha : NULL, id);
273762306a36Sopenharmony_ci
273862306a36Sopenharmony_ci	va_start(va, fmt);
273962306a36Sopenharmony_ci
274062306a36Sopenharmony_ci	vaf.fmt = fmt;
274162306a36Sopenharmony_ci	vaf.va = &va;
274262306a36Sopenharmony_ci
274362306a36Sopenharmony_ci	switch (level) {
274462306a36Sopenharmony_ci	case ql_log_fatal: /* FATAL LOG */
274562306a36Sopenharmony_ci		pr_crit("%s%pV", pbuf, &vaf);
274662306a36Sopenharmony_ci		break;
274762306a36Sopenharmony_ci	case ql_log_warn:
274862306a36Sopenharmony_ci		pr_err("%s%pV", pbuf, &vaf);
274962306a36Sopenharmony_ci		break;
275062306a36Sopenharmony_ci	case ql_log_info:
275162306a36Sopenharmony_ci		pr_warn("%s%pV", pbuf, &vaf);
275262306a36Sopenharmony_ci		break;
275362306a36Sopenharmony_ci	default:
275462306a36Sopenharmony_ci		pr_info("%s%pV", pbuf, &vaf);
275562306a36Sopenharmony_ci		break;
275662306a36Sopenharmony_ci	}
275762306a36Sopenharmony_ci
275862306a36Sopenharmony_ci	va_end(va);
275962306a36Sopenharmony_ci}
276062306a36Sopenharmony_ci
276162306a36Sopenharmony_ci/*
276262306a36Sopenharmony_ci * This function is for formatting and logging debug information.
276362306a36Sopenharmony_ci * It is to be used when vha is available. It formats the message
276462306a36Sopenharmony_ci * and logs it to the messages file.
276562306a36Sopenharmony_ci * parameters:
276662306a36Sopenharmony_ci * level: The level of the debug messages to be printed.
276762306a36Sopenharmony_ci *        If ql2xextended_error_logging value is correctly set,
276862306a36Sopenharmony_ci *        this message will appear in the messages file.
276962306a36Sopenharmony_ci * vha:   Pointer to the scsi_qla_host_t.
277062306a36Sopenharmony_ci * id:    This is a unique identifier for the level. It identifies the
277162306a36Sopenharmony_ci *        part of the code from where the message originated.
277262306a36Sopenharmony_ci * msg:   The message to be displayed.
277362306a36Sopenharmony_ci */
277462306a36Sopenharmony_civoid
277562306a36Sopenharmony_ciql_dbg_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
277662306a36Sopenharmony_ci    const char *fmt, ...)
277762306a36Sopenharmony_ci{
277862306a36Sopenharmony_ci	va_list va;
277962306a36Sopenharmony_ci	struct va_format vaf;
278062306a36Sopenharmony_ci	char pbuf[128];
278162306a36Sopenharmony_ci
278262306a36Sopenharmony_ci	ql_ktrace(1, level, pbuf, NULL, qpair ? qpair->vha : NULL, id, fmt);
278362306a36Sopenharmony_ci
278462306a36Sopenharmony_ci	if (!ql_mask_match(level))
278562306a36Sopenharmony_ci		return;
278662306a36Sopenharmony_ci
278762306a36Sopenharmony_ci	va_start(va, fmt);
278862306a36Sopenharmony_ci
278962306a36Sopenharmony_ci	vaf.fmt = fmt;
279062306a36Sopenharmony_ci	vaf.va = &va;
279162306a36Sopenharmony_ci
279262306a36Sopenharmony_ci	if (!pbuf[0]) /* set by ql_ktrace */
279362306a36Sopenharmony_ci		ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL,
279462306a36Sopenharmony_ci			      qpair ? qpair->vha : NULL, id + ql_dbg_offset);
279562306a36Sopenharmony_ci
279662306a36Sopenharmony_ci	pr_warn("%s%pV", pbuf, &vaf);
279762306a36Sopenharmony_ci
279862306a36Sopenharmony_ci	va_end(va);
279962306a36Sopenharmony_ci
280062306a36Sopenharmony_ci}
2801