xref: /linux/drivers/scsi/qla2xxx/qla_dbg.c (revision 7108b76e87e9a31099f5d4ac0aed6c3b77dce728)
11da177e4SLinus Torvalds /*
2fa90c54fSAndrew Vasquez  * QLogic Fibre Channel HBA Driver
3bd21eaf9SArmen Baloyan  * Copyright (c)  2003-2014 QLogic Corporation
41da177e4SLinus Torvalds  *
5fa90c54fSAndrew Vasquez  * See LICENSE.qla2xxx for copyright and licensing details.
61da177e4SLinus Torvalds  */
73ce8866cSSaurav Kashyap 
83ce8866cSSaurav Kashyap /*
93ce8866cSSaurav Kashyap  * Table for showing the current message id in use for particular level
103ce8866cSSaurav Kashyap  * Change this table for addition of log/debug messages.
11e02587d7SArun Easi  * ----------------------------------------------------------------------
12e02587d7SArun Easi  * |             Level            |   Last Value Used  |     Holes	|
13e02587d7SArun Easi  * ----------------------------------------------------------------------
14f73cb695SChad Dupuis  * | Module Init and Probe        |       0x017d       | 0x004b,0x0141	|
15f73cb695SChad Dupuis  * |                              |                    | 0x0144,0x0146	|
16f73cb695SChad Dupuis  * |                              |                    | 0x015b-0x0160	|
17f73cb695SChad Dupuis  * |                              |                    | 0x016e-0x0170	|
18e8887c51SJoe Carnuccio  * | Mailbox commands             |       0x118d       | 0x1018-0x1019	|
191ae47cf3SJoe Carnuccio  * |                              |                    | 0x10ca         |
20f73cb695SChad Dupuis  * |                              |                    | 0x1115-0x1116  |
21f73cb695SChad Dupuis  * |                              |                    | 0x111a-0x111b	|
22f73cb695SChad Dupuis  * |                              |                    | 0x1155-0x1158  |
238ae6d9c7SGiridhar Malavali  * | Device Discovery             |       0x2095       | 0x2020-0x2022, |
246593d5bdSBart Van Assche  * |                              |                    | 0x2011-0x2012, |
252a8593f8SSaurav Kashyap  * |                              |                    | 0x2016         |
2636008cf1SChad Dupuis  * | Queue Command and IO tracing |       0x3059       | 0x3006-0x300b  |
279e522cd8SArun Easi  * |                              |                    | 0x3027-0x3028  |
288ae6d9c7SGiridhar Malavali  * |                              |                    | 0x303d-0x3041  |
298ae6d9c7SGiridhar Malavali  * |                              |                    | 0x302d,0x3033  |
308ae6d9c7SGiridhar Malavali  * |                              |                    | 0x3036,0x3038  |
318ae6d9c7SGiridhar Malavali  * |                              |                    | 0x303a		|
32e8f5e95dSArmen Baloyan  * | DPC Thread                   |       0x4023       | 0x4002,0x4013  |
33454073c9SSantosh Vernekar  * | Async Events                 |       0x5087       | 0x502b-0x502f  |
349ba56b95SGiridhar Malavali  * |                              |                    | 0x5047,0x5052  |
356ddcfef7SSaurav Kashyap  * |                              |                    | 0x5084,0x5075	|
36a78951b2SChad Dupuis  * |                              |                    | 0x503d,0x5044  |
37faef62d1SArmen Baloyan  * |                              |                    | 0x507b		|
3871e56003SArmen Baloyan  * | Timer Routines               |       0x6012       |                |
39f73cb695SChad Dupuis  * | User Space Interactions      |       0x70e2       | 0x7018,0x702e  |
40f73cb695SChad Dupuis  * |				  |		       | 0x7020,0x7024  |
41f73cb695SChad Dupuis  * |                              |                    | 0x7039,0x7045  |
42f73cb695SChad Dupuis  * |                              |                    | 0x7073-0x7075  |
43f73cb695SChad Dupuis  * |                              |                    | 0x70a5-0x70a6  |
44f73cb695SChad Dupuis  * |                              |                    | 0x70a8,0x70ab  |
45f73cb695SChad Dupuis  * |                              |                    | 0x70ad-0x70ae  |
46f73cb695SChad Dupuis  * |                              |                    | 0x70d7-0x70db  |
47f73cb695SChad Dupuis  * |                              |                    | 0x70de-0x70df  |
48*7108b76eSChad Dupuis  * | Task Management              |       0x803d       | 0x8000,0x800b  |
49*7108b76eSChad Dupuis  * |                              |                    | 0x8025,0x8026  |
50*7108b76eSChad Dupuis  * |                              |                    | 0x8031,0x8032  |
51*7108b76eSChad Dupuis  * |                              |                    | 0x8039,0x803c  |
525f28d2d7SSaurav Kashyap  * | AER/EEH                      |       0x9011       |		|
53e02587d7SArun Easi  * | Virtual Port                 |       0xa007       |		|
5427f4b72fSAtul Deshmukh  * | ISP82XX Specific             |       0xb157       | 0xb002,0xb024  |
557ec0effdSAtul Deshmukh  * |                              |                    | 0xb09e,0xb0ae  |
56a018d8ffSHiral Patel  * |				  |		       | 0xb0c3,0xb0c6  |
577ec0effdSAtul Deshmukh  * |                              |                    | 0xb0e0-0xb0ef  |
587ec0effdSAtul Deshmukh  * |                              |                    | 0xb085,0xb0dc  |
597ec0effdSAtul Deshmukh  * |                              |                    | 0xb107,0xb108  |
607ec0effdSAtul Deshmukh  * |                              |                    | 0xb111,0xb11e  |
617ec0effdSAtul Deshmukh  * |                              |                    | 0xb12c,0xb12d  |
627ec0effdSAtul Deshmukh  * |                              |                    | 0xb13a,0xb142  |
637ec0effdSAtul Deshmukh  * |                              |                    | 0xb13c-0xb140  |
646ddcfef7SSaurav Kashyap  * |                              |                    | 0xb149		|
656246b8a1SGiridhar Malavali  * | MultiQ                       |       0xc00c       |		|
66c0496401SJoe Carnuccio  * | Misc                         |       0xd212       | 0xd017-0xd019	|
67f73cb695SChad Dupuis  * |                              |                    | 0xd020		|
68c0496401SJoe Carnuccio  * |                              |                    | 0xd030-0xd0ff	|
69f73cb695SChad Dupuis  * |                              |                    | 0xd101-0xd1fe	|
70c0496401SJoe Carnuccio  * |                              |                    | 0xd213-0xd2fe	|
71f83adb61SQuinn Tran  * | Target Mode		  |	  0xe078       |		|
726ddcfef7SSaurav Kashyap  * | Target Mode Management	  |	  0xf072       | 0xf002-0xf003	|
736ddcfef7SSaurav Kashyap  * |                              |                    | 0xf046-0xf049  |
742d70c103SNicholas Bellinger  * | Target Mode Task Management  |	  0x1000b      |		|
75e02587d7SArun Easi  * ----------------------------------------------------------------------
763ce8866cSSaurav Kashyap  */
773ce8866cSSaurav Kashyap 
781da177e4SLinus Torvalds #include "qla_def.h"
791da177e4SLinus Torvalds 
801da177e4SLinus Torvalds #include <linux/delay.h>
811da177e4SLinus Torvalds 
823ce8866cSSaurav Kashyap static uint32_t ql_dbg_offset = 0x800;
833ce8866cSSaurav Kashyap 
84a7a167bfSAndrew Vasquez static inline void
857b867cf7SAnirban Chakraborty qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump)
86a7a167bfSAndrew Vasquez {
87a7a167bfSAndrew Vasquez 	fw_dump->fw_major_version = htonl(ha->fw_major_version);
88a7a167bfSAndrew Vasquez 	fw_dump->fw_minor_version = htonl(ha->fw_minor_version);
89a7a167bfSAndrew Vasquez 	fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version);
90a7a167bfSAndrew Vasquez 	fw_dump->fw_attributes = htonl(ha->fw_attributes);
91a7a167bfSAndrew Vasquez 
92a7a167bfSAndrew Vasquez 	fw_dump->vendor = htonl(ha->pdev->vendor);
93a7a167bfSAndrew Vasquez 	fw_dump->device = htonl(ha->pdev->device);
94a7a167bfSAndrew Vasquez 	fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor);
95a7a167bfSAndrew Vasquez 	fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device);
96a7a167bfSAndrew Vasquez }
97a7a167bfSAndrew Vasquez 
98a7a167bfSAndrew Vasquez static inline void *
9973208dfdSAnirban Chakraborty qla2xxx_copy_queues(struct qla_hw_data *ha, void *ptr)
100a7a167bfSAndrew Vasquez {
10173208dfdSAnirban Chakraborty 	struct req_que *req = ha->req_q_map[0];
10273208dfdSAnirban Chakraborty 	struct rsp_que *rsp = ha->rsp_q_map[0];
103a7a167bfSAndrew Vasquez 	/* Request queue. */
1047b867cf7SAnirban Chakraborty 	memcpy(ptr, req->ring, req->length *
105a7a167bfSAndrew Vasquez 	    sizeof(request_t));
106a7a167bfSAndrew Vasquez 
107a7a167bfSAndrew Vasquez 	/* Response queue. */
1087b867cf7SAnirban Chakraborty 	ptr += req->length * sizeof(request_t);
1097b867cf7SAnirban Chakraborty 	memcpy(ptr, rsp->ring, rsp->length  *
110a7a167bfSAndrew Vasquez 	    sizeof(response_t));
111a7a167bfSAndrew Vasquez 
1127b867cf7SAnirban Chakraborty 	return ptr + (rsp->length * sizeof(response_t));
113a7a167bfSAndrew Vasquez }
1141da177e4SLinus Torvalds 
115f73cb695SChad Dupuis int
116f73cb695SChad Dupuis qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
117f73cb695SChad Dupuis 	uint32_t ram_dwords, void **nxt)
118f73cb695SChad Dupuis {
119f73cb695SChad Dupuis 	int rval;
120f73cb695SChad Dupuis 	uint32_t cnt, stat, timer, dwords, idx;
121f73cb695SChad Dupuis 	uint16_t mb0, mb1;
122f73cb695SChad Dupuis 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
123f73cb695SChad Dupuis 	dma_addr_t dump_dma = ha->gid_list_dma;
124f73cb695SChad Dupuis 	uint32_t *dump = (uint32_t *)ha->gid_list;
125f73cb695SChad Dupuis 
126f73cb695SChad Dupuis 	rval = QLA_SUCCESS;
127f73cb695SChad Dupuis 	mb0 = 0;
128f73cb695SChad Dupuis 
129f73cb695SChad Dupuis 	WRT_REG_WORD(&reg->mailbox0, MBC_LOAD_DUMP_MPI_RAM);
130f73cb695SChad Dupuis 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
131f73cb695SChad Dupuis 
132f73cb695SChad Dupuis 	dwords = qla2x00_gid_list_size(ha) / 4;
133f73cb695SChad Dupuis 	for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS;
134f73cb695SChad Dupuis 	    cnt += dwords, addr += dwords) {
135f73cb695SChad Dupuis 		if (cnt + dwords > ram_dwords)
136f73cb695SChad Dupuis 			dwords = ram_dwords - cnt;
137f73cb695SChad Dupuis 
138f73cb695SChad Dupuis 		WRT_REG_WORD(&reg->mailbox1, LSW(addr));
139f73cb695SChad Dupuis 		WRT_REG_WORD(&reg->mailbox8, MSW(addr));
140f73cb695SChad Dupuis 
141f73cb695SChad Dupuis 		WRT_REG_WORD(&reg->mailbox2, MSW(dump_dma));
142f73cb695SChad Dupuis 		WRT_REG_WORD(&reg->mailbox3, LSW(dump_dma));
143f73cb695SChad Dupuis 		WRT_REG_WORD(&reg->mailbox6, MSW(MSD(dump_dma)));
144f73cb695SChad Dupuis 		WRT_REG_WORD(&reg->mailbox7, LSW(MSD(dump_dma)));
145f73cb695SChad Dupuis 
146f73cb695SChad Dupuis 		WRT_REG_WORD(&reg->mailbox4, MSW(dwords));
147f73cb695SChad Dupuis 		WRT_REG_WORD(&reg->mailbox5, LSW(dwords));
148f73cb695SChad Dupuis 
149f73cb695SChad Dupuis 		WRT_REG_WORD(&reg->mailbox9, 0);
150f73cb695SChad Dupuis 		WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
151f73cb695SChad Dupuis 
152f73cb695SChad Dupuis 		ha->flags.mbox_int = 0;
153f73cb695SChad Dupuis 		for (timer = 6000000; timer; timer--) {
154f73cb695SChad Dupuis 			/* Check for pending interrupts. */
155f73cb695SChad Dupuis 			stat = RD_REG_DWORD(&reg->host_status);
156f73cb695SChad Dupuis 			if (stat & HSRX_RISC_INT) {
157f73cb695SChad Dupuis 				stat &= 0xff;
158f73cb695SChad Dupuis 
159f73cb695SChad Dupuis 				if (stat == 0x1 || stat == 0x2 ||
160f73cb695SChad Dupuis 				    stat == 0x10 || stat == 0x11) {
161f73cb695SChad Dupuis 					set_bit(MBX_INTERRUPT,
162f73cb695SChad Dupuis 					    &ha->mbx_cmd_flags);
163f73cb695SChad Dupuis 
164f73cb695SChad Dupuis 					mb0 = RD_REG_WORD(&reg->mailbox0);
165f73cb695SChad Dupuis 					mb1 = RD_REG_WORD(&reg->mailbox1);
166f73cb695SChad Dupuis 
167f73cb695SChad Dupuis 					WRT_REG_DWORD(&reg->hccr,
168f73cb695SChad Dupuis 					    HCCRX_CLR_RISC_INT);
169f73cb695SChad Dupuis 					RD_REG_DWORD(&reg->hccr);
170f73cb695SChad Dupuis 					break;
171f73cb695SChad Dupuis 				}
172f73cb695SChad Dupuis 
173f73cb695SChad Dupuis 				/* Clear this intr; it wasn't a mailbox intr */
174f73cb695SChad Dupuis 				WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
175f73cb695SChad Dupuis 				RD_REG_DWORD(&reg->hccr);
176f73cb695SChad Dupuis 			}
177f73cb695SChad Dupuis 			udelay(5);
178f73cb695SChad Dupuis 		}
179f73cb695SChad Dupuis 		ha->flags.mbox_int = 1;
180f73cb695SChad Dupuis 
181f73cb695SChad Dupuis 		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
182f73cb695SChad Dupuis 			rval = mb0 & MBS_MASK;
183f73cb695SChad Dupuis 			for (idx = 0; idx < dwords; idx++)
184f73cb695SChad Dupuis 				ram[cnt + idx] = IS_QLA27XX(ha) ?
185f73cb695SChad Dupuis 				    le32_to_cpu(dump[idx]) : swab32(dump[idx]);
186f73cb695SChad Dupuis 		} else {
187f73cb695SChad Dupuis 			rval = QLA_FUNCTION_FAILED;
188f73cb695SChad Dupuis 		}
189f73cb695SChad Dupuis 	}
190f73cb695SChad Dupuis 
191f73cb695SChad Dupuis 	*nxt = rval == QLA_SUCCESS ? &ram[cnt] : NULL;
192f73cb695SChad Dupuis 	return rval;
193f73cb695SChad Dupuis }
194f73cb695SChad Dupuis 
195f73cb695SChad Dupuis int
1967b867cf7SAnirban Chakraborty qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
197c5722708SAndrew Vasquez     uint32_t ram_dwords, void **nxt)
198c3a2f0dfSAndrew Vasquez {
199c3a2f0dfSAndrew Vasquez 	int rval;
200c5722708SAndrew Vasquez 	uint32_t cnt, stat, timer, dwords, idx;
201c5722708SAndrew Vasquez 	uint16_t mb0;
202c3a2f0dfSAndrew Vasquez 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
203c5722708SAndrew Vasquez 	dma_addr_t dump_dma = ha->gid_list_dma;
204c5722708SAndrew Vasquez 	uint32_t *dump = (uint32_t *)ha->gid_list;
205c3a2f0dfSAndrew Vasquez 
206c3a2f0dfSAndrew Vasquez 	rval = QLA_SUCCESS;
207c5722708SAndrew Vasquez 	mb0 = 0;
208c5722708SAndrew Vasquez 
209c5722708SAndrew Vasquez 	WRT_REG_WORD(&reg->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED);
210c5722708SAndrew Vasquez 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
211c5722708SAndrew Vasquez 
212642ef983SChad Dupuis 	dwords = qla2x00_gid_list_size(ha) / 4;
213c5722708SAndrew Vasquez 	for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS;
214c5722708SAndrew Vasquez 	    cnt += dwords, addr += dwords) {
215c5722708SAndrew Vasquez 		if (cnt + dwords > ram_dwords)
216c5722708SAndrew Vasquez 			dwords = ram_dwords - cnt;
217c5722708SAndrew Vasquez 
218c5722708SAndrew Vasquez 		WRT_REG_WORD(&reg->mailbox1, LSW(addr));
219c5722708SAndrew Vasquez 		WRT_REG_WORD(&reg->mailbox8, MSW(addr));
220c5722708SAndrew Vasquez 
221c5722708SAndrew Vasquez 		WRT_REG_WORD(&reg->mailbox2, MSW(dump_dma));
222c5722708SAndrew Vasquez 		WRT_REG_WORD(&reg->mailbox3, LSW(dump_dma));
223c5722708SAndrew Vasquez 		WRT_REG_WORD(&reg->mailbox6, MSW(MSD(dump_dma)));
224c5722708SAndrew Vasquez 		WRT_REG_WORD(&reg->mailbox7, LSW(MSD(dump_dma)));
225c5722708SAndrew Vasquez 
226c5722708SAndrew Vasquez 		WRT_REG_WORD(&reg->mailbox4, MSW(dwords));
227c5722708SAndrew Vasquez 		WRT_REG_WORD(&reg->mailbox5, LSW(dwords));
228c5722708SAndrew Vasquez 		WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
229c5722708SAndrew Vasquez 
230f73cb695SChad Dupuis 		ha->flags.mbox_int = 0;
231c5722708SAndrew Vasquez 		for (timer = 6000000; timer; timer--) {
232c5722708SAndrew Vasquez 			/* Check for pending interrupts. */
233c5722708SAndrew Vasquez 			stat = RD_REG_DWORD(&reg->host_status);
234c5722708SAndrew Vasquez 			if (stat & HSRX_RISC_INT) {
235c5722708SAndrew Vasquez 				stat &= 0xff;
236c5722708SAndrew Vasquez 
237c5722708SAndrew Vasquez 				if (stat == 0x1 || stat == 0x2 ||
238c5722708SAndrew Vasquez 				    stat == 0x10 || stat == 0x11) {
239c5722708SAndrew Vasquez 					set_bit(MBX_INTERRUPT,
240c5722708SAndrew Vasquez 					    &ha->mbx_cmd_flags);
241c5722708SAndrew Vasquez 
242c5722708SAndrew Vasquez 					mb0 = RD_REG_WORD(&reg->mailbox0);
243c5722708SAndrew Vasquez 
244c5722708SAndrew Vasquez 					WRT_REG_DWORD(&reg->hccr,
245c5722708SAndrew Vasquez 					    HCCRX_CLR_RISC_INT);
246c5722708SAndrew Vasquez 					RD_REG_DWORD(&reg->hccr);
247c5722708SAndrew Vasquez 					break;
248c5722708SAndrew Vasquez 				}
249c5722708SAndrew Vasquez 
250c5722708SAndrew Vasquez 				/* Clear this intr; it wasn't a mailbox intr */
251c5722708SAndrew Vasquez 				WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
252c5722708SAndrew Vasquez 				RD_REG_DWORD(&reg->hccr);
253c5722708SAndrew Vasquez 			}
254c5722708SAndrew Vasquez 			udelay(5);
255c5722708SAndrew Vasquez 		}
256f73cb695SChad Dupuis 		ha->flags.mbox_int = 1;
257c5722708SAndrew Vasquez 
258c5722708SAndrew Vasquez 		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
259c5722708SAndrew Vasquez 			rval = mb0 & MBS_MASK;
260c5722708SAndrew Vasquez 			for (idx = 0; idx < dwords; idx++)
261f73cb695SChad Dupuis 				ram[cnt + idx] = IS_QLA27XX(ha) ?
262f73cb695SChad Dupuis 				    le32_to_cpu(dump[idx]) : swab32(dump[idx]);
263c5722708SAndrew Vasquez 		} else {
264c5722708SAndrew Vasquez 			rval = QLA_FUNCTION_FAILED;
265c5722708SAndrew Vasquez 		}
266c5722708SAndrew Vasquez 	}
267c5722708SAndrew Vasquez 
268c5722708SAndrew Vasquez 	*nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL;
269c5722708SAndrew Vasquez 	return rval;
270c5722708SAndrew Vasquez }
271c5722708SAndrew Vasquez 
272c5722708SAndrew Vasquez static int
2737b867cf7SAnirban Chakraborty qla24xx_dump_memory(struct qla_hw_data *ha, uint32_t *code_ram,
274c5722708SAndrew Vasquez     uint32_t cram_size, void **nxt)
275c5722708SAndrew Vasquez {
276c5722708SAndrew Vasquez 	int rval;
277c3a2f0dfSAndrew Vasquez 
278c3a2f0dfSAndrew Vasquez 	/* Code RAM. */
279c5722708SAndrew Vasquez 	rval = qla24xx_dump_ram(ha, 0x20000, code_ram, cram_size / 4, nxt);
280c5722708SAndrew Vasquez 	if (rval != QLA_SUCCESS)
281c3a2f0dfSAndrew Vasquez 		return rval;
282c5722708SAndrew Vasquez 
28361f098ddSHiral Patel 	set_bit(RISC_SRAM_DUMP_CMPL, &ha->fw_dump_cap_flags);
28461f098ddSHiral Patel 
285c5722708SAndrew Vasquez 	/* External Memory. */
28661f098ddSHiral Patel 	rval = qla24xx_dump_ram(ha, 0x100000, *nxt,
287c5722708SAndrew Vasquez 	    ha->fw_memory_size - 0x100000 + 1, nxt);
28861f098ddSHiral Patel 	if (rval == QLA_SUCCESS)
28961f098ddSHiral Patel 		set_bit(RISC_EXT_MEM_DUMP_CMPL, &ha->fw_dump_cap_flags);
29061f098ddSHiral Patel 
29161f098ddSHiral Patel 	return rval;
292c3a2f0dfSAndrew Vasquez }
293c3a2f0dfSAndrew Vasquez 
294c81d04c9SAndrew Vasquez static uint32_t *
295c81d04c9SAndrew Vasquez qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase,
296c81d04c9SAndrew Vasquez     uint32_t count, uint32_t *buf)
297c81d04c9SAndrew Vasquez {
298c81d04c9SAndrew Vasquez 	uint32_t __iomem *dmp_reg;
299c81d04c9SAndrew Vasquez 
300c81d04c9SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_addr, iobase);
301c81d04c9SAndrew Vasquez 	dmp_reg = &reg->iobase_window;
302c81d04c9SAndrew Vasquez 	while (count--)
303c81d04c9SAndrew Vasquez 		*buf++ = htonl(RD_REG_DWORD(dmp_reg++));
304c81d04c9SAndrew Vasquez 
305c81d04c9SAndrew Vasquez 	return buf;
306c81d04c9SAndrew Vasquez }
307c81d04c9SAndrew Vasquez 
3082f389fc4SHiral Patel void
30961f098ddSHiral Patel qla24xx_pause_risc(struct device_reg_24xx __iomem *reg, struct qla_hw_data *ha)
310c81d04c9SAndrew Vasquez {
311c81d04c9SAndrew Vasquez 	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
312c81d04c9SAndrew Vasquez 
3132f389fc4SHiral Patel 	/* 100 usec delay is sufficient enough for hardware to pause RISC */
3142f389fc4SHiral Patel 	udelay(100);
31561f098ddSHiral Patel 	if (RD_REG_DWORD(&reg->host_status) & HSRX_RISC_PAUSED)
31661f098ddSHiral Patel 		set_bit(RISC_PAUSE_CMPL, &ha->fw_dump_cap_flags);
317c81d04c9SAndrew Vasquez }
318c81d04c9SAndrew Vasquez 
319f73cb695SChad Dupuis int
3207b867cf7SAnirban Chakraborty qla24xx_soft_reset(struct qla_hw_data *ha)
321c81d04c9SAndrew Vasquez {
322c81d04c9SAndrew Vasquez 	int rval = QLA_SUCCESS;
323c81d04c9SAndrew Vasquez 	uint32_t cnt;
3242f389fc4SHiral Patel 	uint16_t wd;
325c81d04c9SAndrew Vasquez 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
326c81d04c9SAndrew Vasquez 
3272f389fc4SHiral Patel 	/*
3282f389fc4SHiral Patel 	 * Reset RISC. The delay is dependent on system architecture.
3292f389fc4SHiral Patel 	 * Driver can proceed with the reset sequence after waiting
3302f389fc4SHiral Patel 	 * for a timeout period.
3312f389fc4SHiral Patel 	 */
332c81d04c9SAndrew Vasquez 	WRT_REG_DWORD(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
333c81d04c9SAndrew Vasquez 	for (cnt = 0; cnt < 30000; cnt++) {
334c81d04c9SAndrew Vasquez 		if ((RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
335c81d04c9SAndrew Vasquez 			break;
336c81d04c9SAndrew Vasquez 
337c81d04c9SAndrew Vasquez 		udelay(10);
338c81d04c9SAndrew Vasquez 	}
33961f098ddSHiral Patel 	if (!(RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE))
34061f098ddSHiral Patel 		set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags);
341c81d04c9SAndrew Vasquez 
342c81d04c9SAndrew Vasquez 	WRT_REG_DWORD(&reg->ctrl_status,
343c81d04c9SAndrew Vasquez 	    CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
344c81d04c9SAndrew Vasquez 	pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
345c81d04c9SAndrew Vasquez 
346c81d04c9SAndrew Vasquez 	udelay(100);
347c81d04c9SAndrew Vasquez 
348c81d04c9SAndrew Vasquez 	/* Wait for soft-reset to complete. */
349c81d04c9SAndrew Vasquez 	for (cnt = 0; cnt < 30000; cnt++) {
350c81d04c9SAndrew Vasquez 		if ((RD_REG_DWORD(&reg->ctrl_status) &
351c81d04c9SAndrew Vasquez 		    CSRX_ISP_SOFT_RESET) == 0)
352c81d04c9SAndrew Vasquez 			break;
353c81d04c9SAndrew Vasquez 
354c81d04c9SAndrew Vasquez 		udelay(10);
355c81d04c9SAndrew Vasquez 	}
35661f098ddSHiral Patel 	if (!(RD_REG_DWORD(&reg->ctrl_status) & CSRX_ISP_SOFT_RESET))
35761f098ddSHiral Patel 		set_bit(ISP_RESET_CMPL, &ha->fw_dump_cap_flags);
35861f098ddSHiral Patel 
359c81d04c9SAndrew Vasquez 	WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
360c81d04c9SAndrew Vasquez 	RD_REG_DWORD(&reg->hccr);             /* PCI Posting. */
361c81d04c9SAndrew Vasquez 
3622f389fc4SHiral Patel 	for (cnt = 10000; RD_REG_WORD(&reg->mailbox0) != 0 &&
363c81d04c9SAndrew Vasquez 	    rval == QLA_SUCCESS; cnt--) {
364c81d04c9SAndrew Vasquez 		if (cnt)
3652f389fc4SHiral Patel 			udelay(10);
366c81d04c9SAndrew Vasquez 		else
367c81d04c9SAndrew Vasquez 			rval = QLA_FUNCTION_TIMEOUT;
368c81d04c9SAndrew Vasquez 	}
36961f098ddSHiral Patel 	if (rval == QLA_SUCCESS)
37061f098ddSHiral Patel 		set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
371c81d04c9SAndrew Vasquez 
372c81d04c9SAndrew Vasquez 	return rval;
373c81d04c9SAndrew Vasquez }
374c81d04c9SAndrew Vasquez 
375c5722708SAndrew Vasquez static int
3767b867cf7SAnirban Chakraborty qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram,
377e18e963bSAndrew Vasquez     uint32_t ram_words, void **nxt)
378c5722708SAndrew Vasquez {
379c5722708SAndrew Vasquez 	int rval;
380c5722708SAndrew Vasquez 	uint32_t cnt, stat, timer, words, idx;
381c5722708SAndrew Vasquez 	uint16_t mb0;
382c5722708SAndrew Vasquez 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
383c5722708SAndrew Vasquez 	dma_addr_t dump_dma = ha->gid_list_dma;
384c5722708SAndrew Vasquez 	uint16_t *dump = (uint16_t *)ha->gid_list;
385c5722708SAndrew Vasquez 
386c5722708SAndrew Vasquez 	rval = QLA_SUCCESS;
387c5722708SAndrew Vasquez 	mb0 = 0;
388c5722708SAndrew Vasquez 
389c5722708SAndrew Vasquez 	WRT_MAILBOX_REG(ha, reg, 0, MBC_DUMP_RISC_RAM_EXTENDED);
390c5722708SAndrew Vasquez 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
391c5722708SAndrew Vasquez 
392642ef983SChad Dupuis 	words = qla2x00_gid_list_size(ha) / 2;
393c5722708SAndrew Vasquez 	for (cnt = 0; cnt < ram_words && rval == QLA_SUCCESS;
394c5722708SAndrew Vasquez 	    cnt += words, addr += words) {
395c5722708SAndrew Vasquez 		if (cnt + words > ram_words)
396c5722708SAndrew Vasquez 			words = ram_words - cnt;
397c5722708SAndrew Vasquez 
398c5722708SAndrew Vasquez 		WRT_MAILBOX_REG(ha, reg, 1, LSW(addr));
399c5722708SAndrew Vasquez 		WRT_MAILBOX_REG(ha, reg, 8, MSW(addr));
400c5722708SAndrew Vasquez 
401c5722708SAndrew Vasquez 		WRT_MAILBOX_REG(ha, reg, 2, MSW(dump_dma));
402c5722708SAndrew Vasquez 		WRT_MAILBOX_REG(ha, reg, 3, LSW(dump_dma));
403c5722708SAndrew Vasquez 		WRT_MAILBOX_REG(ha, reg, 6, MSW(MSD(dump_dma)));
404c5722708SAndrew Vasquez 		WRT_MAILBOX_REG(ha, reg, 7, LSW(MSD(dump_dma)));
405c5722708SAndrew Vasquez 
406c5722708SAndrew Vasquez 		WRT_MAILBOX_REG(ha, reg, 4, words);
407c5722708SAndrew Vasquez 		WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
408c5722708SAndrew Vasquez 
409c5722708SAndrew Vasquez 		for (timer = 6000000; timer; timer--) {
410c5722708SAndrew Vasquez 			/* Check for pending interrupts. */
411c5722708SAndrew Vasquez 			stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
412c5722708SAndrew Vasquez 			if (stat & HSR_RISC_INT) {
413c5722708SAndrew Vasquez 				stat &= 0xff;
414c5722708SAndrew Vasquez 
415c5722708SAndrew Vasquez 				if (stat == 0x1 || stat == 0x2) {
416c5722708SAndrew Vasquez 					set_bit(MBX_INTERRUPT,
417c5722708SAndrew Vasquez 					    &ha->mbx_cmd_flags);
418c5722708SAndrew Vasquez 
419c5722708SAndrew Vasquez 					mb0 = RD_MAILBOX_REG(ha, reg, 0);
420c5722708SAndrew Vasquez 
421c5722708SAndrew Vasquez 					/* Release mailbox registers. */
422c5722708SAndrew Vasquez 					WRT_REG_WORD(&reg->semaphore, 0);
423c5722708SAndrew Vasquez 					WRT_REG_WORD(&reg->hccr,
424c5722708SAndrew Vasquez 					    HCCR_CLR_RISC_INT);
425c5722708SAndrew Vasquez 					RD_REG_WORD(&reg->hccr);
426c5722708SAndrew Vasquez 					break;
427c5722708SAndrew Vasquez 				} else if (stat == 0x10 || stat == 0x11) {
428c5722708SAndrew Vasquez 					set_bit(MBX_INTERRUPT,
429c5722708SAndrew Vasquez 					    &ha->mbx_cmd_flags);
430c5722708SAndrew Vasquez 
431c5722708SAndrew Vasquez 					mb0 = RD_MAILBOX_REG(ha, reg, 0);
432c5722708SAndrew Vasquez 
433c5722708SAndrew Vasquez 					WRT_REG_WORD(&reg->hccr,
434c5722708SAndrew Vasquez 					    HCCR_CLR_RISC_INT);
435c5722708SAndrew Vasquez 					RD_REG_WORD(&reg->hccr);
436c5722708SAndrew Vasquez 					break;
437c5722708SAndrew Vasquez 				}
438c5722708SAndrew Vasquez 
439c5722708SAndrew Vasquez 				/* clear this intr; it wasn't a mailbox intr */
440c5722708SAndrew Vasquez 				WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
441c5722708SAndrew Vasquez 				RD_REG_WORD(&reg->hccr);
442c5722708SAndrew Vasquez 			}
443c5722708SAndrew Vasquez 			udelay(5);
444c5722708SAndrew Vasquez 		}
445c5722708SAndrew Vasquez 
446c5722708SAndrew Vasquez 		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
447c5722708SAndrew Vasquez 			rval = mb0 & MBS_MASK;
448c5722708SAndrew Vasquez 			for (idx = 0; idx < words; idx++)
449c5722708SAndrew Vasquez 				ram[cnt + idx] = swab16(dump[idx]);
450c5722708SAndrew Vasquez 		} else {
451c5722708SAndrew Vasquez 			rval = QLA_FUNCTION_FAILED;
452c5722708SAndrew Vasquez 		}
453c5722708SAndrew Vasquez 	}
454c5722708SAndrew Vasquez 
455c5722708SAndrew Vasquez 	*nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL;
456c5722708SAndrew Vasquez 	return rval;
457c5722708SAndrew Vasquez }
458c5722708SAndrew Vasquez 
459c81d04c9SAndrew Vasquez static inline void
460c81d04c9SAndrew Vasquez qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count,
461c81d04c9SAndrew Vasquez     uint16_t *buf)
462c81d04c9SAndrew Vasquez {
463c81d04c9SAndrew Vasquez 	uint16_t __iomem *dmp_reg = &reg->u.isp2300.fb_cmd;
464c81d04c9SAndrew Vasquez 
465c81d04c9SAndrew Vasquez 	while (count--)
466c81d04c9SAndrew Vasquez 		*buf++ = htons(RD_REG_WORD(dmp_reg++));
467c81d04c9SAndrew Vasquez }
468c81d04c9SAndrew Vasquez 
469bb99de67SAndrew Vasquez static inline void *
470bb99de67SAndrew Vasquez qla24xx_copy_eft(struct qla_hw_data *ha, void *ptr)
471bb99de67SAndrew Vasquez {
472bb99de67SAndrew Vasquez 	if (!ha->eft)
473bb99de67SAndrew Vasquez 		return ptr;
474bb99de67SAndrew Vasquez 
475bb99de67SAndrew Vasquez 	memcpy(ptr, ha->eft, ntohl(ha->fw_dump->eft_size));
476bb99de67SAndrew Vasquez 	return ptr + ntohl(ha->fw_dump->eft_size);
477bb99de67SAndrew Vasquez }
478bb99de67SAndrew Vasquez 
479bb99de67SAndrew Vasquez static inline void *
480bb99de67SAndrew Vasquez qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
481bb99de67SAndrew Vasquez {
482bb99de67SAndrew Vasquez 	uint32_t cnt;
483bb99de67SAndrew Vasquez 	uint32_t *iter_reg;
484bb99de67SAndrew Vasquez 	struct qla2xxx_fce_chain *fcec = ptr;
485bb99de67SAndrew Vasquez 
486bb99de67SAndrew Vasquez 	if (!ha->fce)
487bb99de67SAndrew Vasquez 		return ptr;
488bb99de67SAndrew Vasquez 
489bb99de67SAndrew Vasquez 	*last_chain = &fcec->type;
490bb99de67SAndrew Vasquez 	fcec->type = __constant_htonl(DUMP_CHAIN_FCE);
491bb99de67SAndrew Vasquez 	fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) +
492bb99de67SAndrew Vasquez 	    fce_calc_size(ha->fce_bufs));
493bb99de67SAndrew Vasquez 	fcec->size = htonl(fce_calc_size(ha->fce_bufs));
494bb99de67SAndrew Vasquez 	fcec->addr_l = htonl(LSD(ha->fce_dma));
495bb99de67SAndrew Vasquez 	fcec->addr_h = htonl(MSD(ha->fce_dma));
496bb99de67SAndrew Vasquez 
497bb99de67SAndrew Vasquez 	iter_reg = fcec->eregs;
498bb99de67SAndrew Vasquez 	for (cnt = 0; cnt < 8; cnt++)
499bb99de67SAndrew Vasquez 		*iter_reg++ = htonl(ha->fce_mb[cnt]);
500bb99de67SAndrew Vasquez 
501bb99de67SAndrew Vasquez 	memcpy(iter_reg, ha->fce, ntohl(fcec->size));
502bb99de67SAndrew Vasquez 
5033cb0a67dSGiridhar Malavali 	return (char *)iter_reg + ntohl(fcec->size);
504bb99de67SAndrew Vasquez }
505bb99de67SAndrew Vasquez 
506d63ab533SAndrew Vasquez static inline void *
5072d70c103SNicholas Bellinger qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr,
5082d70c103SNicholas Bellinger 	uint32_t **last_chain)
5092d70c103SNicholas Bellinger {
5102d70c103SNicholas Bellinger 	struct qla2xxx_mqueue_chain *q;
5112d70c103SNicholas Bellinger 	struct qla2xxx_mqueue_header *qh;
5122d70c103SNicholas Bellinger 	uint32_t num_queues;
5132d70c103SNicholas Bellinger 	int que;
5142d70c103SNicholas Bellinger 	struct {
5152d70c103SNicholas Bellinger 		int length;
5162d70c103SNicholas Bellinger 		void *ring;
5172d70c103SNicholas Bellinger 	} aq, *aqp;
5182d70c103SNicholas Bellinger 
51900876ae8SArun Easi 	if (!ha->tgt.atio_ring)
5202d70c103SNicholas Bellinger 		return ptr;
5212d70c103SNicholas Bellinger 
5222d70c103SNicholas Bellinger 	num_queues = 1;
5232d70c103SNicholas Bellinger 	aqp = &aq;
5242d70c103SNicholas Bellinger 	aqp->length = ha->tgt.atio_q_length;
5252d70c103SNicholas Bellinger 	aqp->ring = ha->tgt.atio_ring;
5262d70c103SNicholas Bellinger 
5272d70c103SNicholas Bellinger 	for (que = 0; que < num_queues; que++) {
5282d70c103SNicholas Bellinger 		/* aqp = ha->atio_q_map[que]; */
5292d70c103SNicholas Bellinger 		q = ptr;
5302d70c103SNicholas Bellinger 		*last_chain = &q->type;
5312d70c103SNicholas Bellinger 		q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
5322d70c103SNicholas Bellinger 		q->chain_size = htonl(
5332d70c103SNicholas Bellinger 		    sizeof(struct qla2xxx_mqueue_chain) +
5342d70c103SNicholas Bellinger 		    sizeof(struct qla2xxx_mqueue_header) +
5352d70c103SNicholas Bellinger 		    (aqp->length * sizeof(request_t)));
5362d70c103SNicholas Bellinger 		ptr += sizeof(struct qla2xxx_mqueue_chain);
5372d70c103SNicholas Bellinger 
5382d70c103SNicholas Bellinger 		/* Add header. */
5392d70c103SNicholas Bellinger 		qh = ptr;
5402d70c103SNicholas Bellinger 		qh->queue = __constant_htonl(TYPE_ATIO_QUEUE);
5412d70c103SNicholas Bellinger 		qh->number = htonl(que);
5422d70c103SNicholas Bellinger 		qh->size = htonl(aqp->length * sizeof(request_t));
5432d70c103SNicholas Bellinger 		ptr += sizeof(struct qla2xxx_mqueue_header);
5442d70c103SNicholas Bellinger 
5452d70c103SNicholas Bellinger 		/* Add data. */
5462d70c103SNicholas Bellinger 		memcpy(ptr, aqp->ring, aqp->length * sizeof(request_t));
5472d70c103SNicholas Bellinger 
5482d70c103SNicholas Bellinger 		ptr += aqp->length * sizeof(request_t);
5492d70c103SNicholas Bellinger 	}
5502d70c103SNicholas Bellinger 
5512d70c103SNicholas Bellinger 	return ptr;
5522d70c103SNicholas Bellinger }
5532d70c103SNicholas Bellinger 
5542d70c103SNicholas Bellinger static inline void *
555050c9bb1SGiridhar Malavali qla25xx_copy_mqueues(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
556050c9bb1SGiridhar Malavali {
557050c9bb1SGiridhar Malavali 	struct qla2xxx_mqueue_chain *q;
558050c9bb1SGiridhar Malavali 	struct qla2xxx_mqueue_header *qh;
559050c9bb1SGiridhar Malavali 	struct req_que *req;
560050c9bb1SGiridhar Malavali 	struct rsp_que *rsp;
561050c9bb1SGiridhar Malavali 	int que;
562050c9bb1SGiridhar Malavali 
563050c9bb1SGiridhar Malavali 	if (!ha->mqenable)
564050c9bb1SGiridhar Malavali 		return ptr;
565050c9bb1SGiridhar Malavali 
566050c9bb1SGiridhar Malavali 	/* Request queues */
567050c9bb1SGiridhar Malavali 	for (que = 1; que < ha->max_req_queues; que++) {
568050c9bb1SGiridhar Malavali 		req = ha->req_q_map[que];
569050c9bb1SGiridhar Malavali 		if (!req)
570050c9bb1SGiridhar Malavali 			break;
571050c9bb1SGiridhar Malavali 
572050c9bb1SGiridhar Malavali 		/* Add chain. */
573050c9bb1SGiridhar Malavali 		q = ptr;
574050c9bb1SGiridhar Malavali 		*last_chain = &q->type;
575050c9bb1SGiridhar Malavali 		q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
576050c9bb1SGiridhar Malavali 		q->chain_size = htonl(
577050c9bb1SGiridhar Malavali 		    sizeof(struct qla2xxx_mqueue_chain) +
578050c9bb1SGiridhar Malavali 		    sizeof(struct qla2xxx_mqueue_header) +
579050c9bb1SGiridhar Malavali 		    (req->length * sizeof(request_t)));
580050c9bb1SGiridhar Malavali 		ptr += sizeof(struct qla2xxx_mqueue_chain);
581050c9bb1SGiridhar Malavali 
582050c9bb1SGiridhar Malavali 		/* Add header. */
583050c9bb1SGiridhar Malavali 		qh = ptr;
584050c9bb1SGiridhar Malavali 		qh->queue = __constant_htonl(TYPE_REQUEST_QUEUE);
585050c9bb1SGiridhar Malavali 		qh->number = htonl(que);
586050c9bb1SGiridhar Malavali 		qh->size = htonl(req->length * sizeof(request_t));
587050c9bb1SGiridhar Malavali 		ptr += sizeof(struct qla2xxx_mqueue_header);
588050c9bb1SGiridhar Malavali 
589050c9bb1SGiridhar Malavali 		/* Add data. */
590050c9bb1SGiridhar Malavali 		memcpy(ptr, req->ring, req->length * sizeof(request_t));
591050c9bb1SGiridhar Malavali 		ptr += req->length * sizeof(request_t);
592050c9bb1SGiridhar Malavali 	}
593050c9bb1SGiridhar Malavali 
594050c9bb1SGiridhar Malavali 	/* Response queues */
595050c9bb1SGiridhar Malavali 	for (que = 1; que < ha->max_rsp_queues; que++) {
596050c9bb1SGiridhar Malavali 		rsp = ha->rsp_q_map[que];
597050c9bb1SGiridhar Malavali 		if (!rsp)
598050c9bb1SGiridhar Malavali 			break;
599050c9bb1SGiridhar Malavali 
600050c9bb1SGiridhar Malavali 		/* Add chain. */
601050c9bb1SGiridhar Malavali 		q = ptr;
602050c9bb1SGiridhar Malavali 		*last_chain = &q->type;
603050c9bb1SGiridhar Malavali 		q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
604050c9bb1SGiridhar Malavali 		q->chain_size = htonl(
605050c9bb1SGiridhar Malavali 		    sizeof(struct qla2xxx_mqueue_chain) +
606050c9bb1SGiridhar Malavali 		    sizeof(struct qla2xxx_mqueue_header) +
607050c9bb1SGiridhar Malavali 		    (rsp->length * sizeof(response_t)));
608050c9bb1SGiridhar Malavali 		ptr += sizeof(struct qla2xxx_mqueue_chain);
609050c9bb1SGiridhar Malavali 
610050c9bb1SGiridhar Malavali 		/* Add header. */
611050c9bb1SGiridhar Malavali 		qh = ptr;
612050c9bb1SGiridhar Malavali 		qh->queue = __constant_htonl(TYPE_RESPONSE_QUEUE);
613050c9bb1SGiridhar Malavali 		qh->number = htonl(que);
614050c9bb1SGiridhar Malavali 		qh->size = htonl(rsp->length * sizeof(response_t));
615050c9bb1SGiridhar Malavali 		ptr += sizeof(struct qla2xxx_mqueue_header);
616050c9bb1SGiridhar Malavali 
617050c9bb1SGiridhar Malavali 		/* Add data. */
618050c9bb1SGiridhar Malavali 		memcpy(ptr, rsp->ring, rsp->length * sizeof(response_t));
619050c9bb1SGiridhar Malavali 		ptr += rsp->length * sizeof(response_t);
620050c9bb1SGiridhar Malavali 	}
621050c9bb1SGiridhar Malavali 
622050c9bb1SGiridhar Malavali 	return ptr;
623050c9bb1SGiridhar Malavali }
624050c9bb1SGiridhar Malavali 
625050c9bb1SGiridhar Malavali static inline void *
626d63ab533SAndrew Vasquez qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
627d63ab533SAndrew Vasquez {
628d63ab533SAndrew Vasquez 	uint32_t cnt, que_idx;
6292afa19a9SAnirban Chakraborty 	uint8_t que_cnt;
630d63ab533SAndrew Vasquez 	struct qla2xxx_mq_chain *mq = ptr;
631da9b1d5cSAndrew Vasquez 	device_reg_t __iomem *reg;
632d63ab533SAndrew Vasquez 
633f73cb695SChad Dupuis 	if (!ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha))
634d63ab533SAndrew Vasquez 		return ptr;
635d63ab533SAndrew Vasquez 
636d63ab533SAndrew Vasquez 	mq = ptr;
637d63ab533SAndrew Vasquez 	*last_chain = &mq->type;
638d63ab533SAndrew Vasquez 	mq->type = __constant_htonl(DUMP_CHAIN_MQ);
639d63ab533SAndrew Vasquez 	mq->chain_size = __constant_htonl(sizeof(struct qla2xxx_mq_chain));
640d63ab533SAndrew Vasquez 
6412afa19a9SAnirban Chakraborty 	que_cnt = ha->max_req_queues > ha->max_rsp_queues ?
6422afa19a9SAnirban Chakraborty 		ha->max_req_queues : ha->max_rsp_queues;
643d63ab533SAndrew Vasquez 	mq->count = htonl(que_cnt);
644d63ab533SAndrew Vasquez 	for (cnt = 0; cnt < que_cnt; cnt++) {
645da9b1d5cSAndrew Vasquez 		reg = ISP_QUE_REG(ha, cnt);
646d63ab533SAndrew Vasquez 		que_idx = cnt * 4;
647da9b1d5cSAndrew Vasquez 		mq->qregs[que_idx] =
648da9b1d5cSAndrew Vasquez 		    htonl(RD_REG_DWORD(&reg->isp25mq.req_q_in));
649da9b1d5cSAndrew Vasquez 		mq->qregs[que_idx+1] =
650da9b1d5cSAndrew Vasquez 		    htonl(RD_REG_DWORD(&reg->isp25mq.req_q_out));
651da9b1d5cSAndrew Vasquez 		mq->qregs[que_idx+2] =
652da9b1d5cSAndrew Vasquez 		    htonl(RD_REG_DWORD(&reg->isp25mq.rsp_q_in));
653da9b1d5cSAndrew Vasquez 		mq->qregs[que_idx+3] =
654da9b1d5cSAndrew Vasquez 		    htonl(RD_REG_DWORD(&reg->isp25mq.rsp_q_out));
655d63ab533SAndrew Vasquez 	}
656d63ab533SAndrew Vasquez 
657d63ab533SAndrew Vasquez 	return ptr + sizeof(struct qla2xxx_mq_chain);
658d63ab533SAndrew Vasquez }
659d63ab533SAndrew Vasquez 
66008de2844SGiridhar Malavali void
6613420d36cSAndrew Vasquez qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
6623420d36cSAndrew Vasquez {
6633420d36cSAndrew Vasquez 	struct qla_hw_data *ha = vha->hw;
6643420d36cSAndrew Vasquez 
6653420d36cSAndrew Vasquez 	if (rval != QLA_SUCCESS) {
6667c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd000,
66761f098ddSHiral Patel 		    "Failed to dump firmware (%x), dump status flags (0x%lx).\n",
66861f098ddSHiral Patel 		    rval, ha->fw_dump_cap_flags);
6693420d36cSAndrew Vasquez 		ha->fw_dumped = 0;
6703420d36cSAndrew Vasquez 	} else {
6717c3df132SSaurav Kashyap 		ql_log(ql_log_info, vha, 0xd001,
67261f098ddSHiral Patel 		    "Firmware dump saved to temp buffer (%ld/%p), dump status flags (0x%lx).\n",
67361f098ddSHiral Patel 		    vha->host_no, ha->fw_dump, ha->fw_dump_cap_flags);
6743420d36cSAndrew Vasquez 		ha->fw_dumped = 1;
6753420d36cSAndrew Vasquez 		qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
6763420d36cSAndrew Vasquez 	}
6773420d36cSAndrew Vasquez }
6783420d36cSAndrew Vasquez 
6791da177e4SLinus Torvalds /**
6801da177e4SLinus Torvalds  * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
6811da177e4SLinus Torvalds  * @ha: HA context
6821da177e4SLinus Torvalds  * @hardware_locked: Called with the hardware_lock
6831da177e4SLinus Torvalds  */
6841da177e4SLinus Torvalds void
6857b867cf7SAnirban Chakraborty qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
6861da177e4SLinus Torvalds {
6871da177e4SLinus Torvalds 	int		rval;
688c5722708SAndrew Vasquez 	uint32_t	cnt;
6897b867cf7SAnirban Chakraborty 	struct qla_hw_data *ha = vha->hw;
6903d71644cSAndrew Vasquez 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
6911da177e4SLinus Torvalds 	uint16_t __iomem *dmp_reg;
6921da177e4SLinus Torvalds 	unsigned long	flags;
6931da177e4SLinus Torvalds 	struct qla2300_fw_dump	*fw;
694c5722708SAndrew Vasquez 	void		*nxt;
69573208dfdSAnirban Chakraborty 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
6961da177e4SLinus Torvalds 
6971da177e4SLinus Torvalds 	flags = 0;
6981da177e4SLinus Torvalds 
6991da177e4SLinus Torvalds 	if (!hardware_locked)
7001da177e4SLinus Torvalds 		spin_lock_irqsave(&ha->hardware_lock, flags);
7011da177e4SLinus Torvalds 
702d4e3e04dSAndrew Vasquez 	if (!ha->fw_dump) {
7037c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd002,
7047c3df132SSaurav Kashyap 		    "No buffer available for dump.\n");
7051da177e4SLinus Torvalds 		goto qla2300_fw_dump_failed;
7061da177e4SLinus Torvalds 	}
7071da177e4SLinus Torvalds 
708d4e3e04dSAndrew Vasquez 	if (ha->fw_dumped) {
7097c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd003,
7107c3df132SSaurav Kashyap 		    "Firmware has been previously dumped (%p) "
7117c3df132SSaurav Kashyap 		    "-- ignoring request.\n",
7127c3df132SSaurav Kashyap 		    ha->fw_dump);
7131da177e4SLinus Torvalds 		goto qla2300_fw_dump_failed;
7141da177e4SLinus Torvalds 	}
715a7a167bfSAndrew Vasquez 	fw = &ha->fw_dump->isp.isp23;
716a7a167bfSAndrew Vasquez 	qla2xxx_prep_dump(ha, ha->fw_dump);
7171da177e4SLinus Torvalds 
7181da177e4SLinus Torvalds 	rval = QLA_SUCCESS;
719a7a167bfSAndrew Vasquez 	fw->hccr = htons(RD_REG_WORD(&reg->hccr));
7201da177e4SLinus Torvalds 
7211da177e4SLinus Torvalds 	/* Pause RISC. */
7221da177e4SLinus Torvalds 	WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
7231da177e4SLinus Torvalds 	if (IS_QLA2300(ha)) {
7241da177e4SLinus Torvalds 		for (cnt = 30000;
7251da177e4SLinus Torvalds 		    (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
7261da177e4SLinus Torvalds 			rval == QLA_SUCCESS; cnt--) {
7271da177e4SLinus Torvalds 			if (cnt)
7281da177e4SLinus Torvalds 				udelay(100);
7291da177e4SLinus Torvalds 			else
7301da177e4SLinus Torvalds 				rval = QLA_FUNCTION_TIMEOUT;
7311da177e4SLinus Torvalds 		}
7321da177e4SLinus Torvalds 	} else {
7331da177e4SLinus Torvalds 		RD_REG_WORD(&reg->hccr);		/* PCI Posting. */
7341da177e4SLinus Torvalds 		udelay(10);
7351da177e4SLinus Torvalds 	}
7361da177e4SLinus Torvalds 
7371da177e4SLinus Torvalds 	if (rval == QLA_SUCCESS) {
738c81d04c9SAndrew Vasquez 		dmp_reg = &reg->flash_address;
7391da177e4SLinus Torvalds 		for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
740a7a167bfSAndrew Vasquez 			fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
7411da177e4SLinus Torvalds 
742c81d04c9SAndrew Vasquez 		dmp_reg = &reg->u.isp2300.req_q_in;
7431da177e4SLinus Torvalds 		for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++)
744a7a167bfSAndrew Vasquez 			fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
7451da177e4SLinus Torvalds 
746c81d04c9SAndrew Vasquez 		dmp_reg = &reg->u.isp2300.mailbox0;
7471da177e4SLinus Torvalds 		for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
748a7a167bfSAndrew Vasquez 			fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
7491da177e4SLinus Torvalds 
7501da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, 0x40);
751c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 32, fw->resp_dma_reg);
7521da177e4SLinus Torvalds 
7531da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, 0x50);
754c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 48, fw->dma_reg);
7551da177e4SLinus Torvalds 
7561da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, 0x00);
757c81d04c9SAndrew Vasquez 		dmp_reg = &reg->risc_hw;
7581da177e4SLinus Torvalds 		for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
759a7a167bfSAndrew Vasquez 			fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
7601da177e4SLinus Torvalds 
7611da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2000);
762c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);
7631da177e4SLinus Torvalds 
7641da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2200);
765c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);
7661da177e4SLinus Torvalds 
7671da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2400);
768c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);
7691da177e4SLinus Torvalds 
7701da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2600);
771c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);
7721da177e4SLinus Torvalds 
7731da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2800);
774c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);
7751da177e4SLinus Torvalds 
7761da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2A00);
777c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);
7781da177e4SLinus Torvalds 
7791da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2C00);
780c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);
7811da177e4SLinus Torvalds 
7821da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2E00);
783c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);
7841da177e4SLinus Torvalds 
7851da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, 0x10);
786c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 64, fw->frame_buf_hdw_reg);
7871da177e4SLinus Torvalds 
7881da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, 0x20);
789c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);
7901da177e4SLinus Torvalds 
7911da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, 0x30);
792c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 64, fw->fpm_b1_reg);
7931da177e4SLinus Torvalds 
7941da177e4SLinus Torvalds 		/* Reset RISC. */
7951da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
7961da177e4SLinus Torvalds 		for (cnt = 0; cnt < 30000; cnt++) {
7971da177e4SLinus Torvalds 			if ((RD_REG_WORD(&reg->ctrl_status) &
7981da177e4SLinus Torvalds 			    CSR_ISP_SOFT_RESET) == 0)
7991da177e4SLinus Torvalds 				break;
8001da177e4SLinus Torvalds 
8011da177e4SLinus Torvalds 			udelay(10);
8021da177e4SLinus Torvalds 		}
8031da177e4SLinus Torvalds 	}
8041da177e4SLinus Torvalds 
8051da177e4SLinus Torvalds 	if (!IS_QLA2300(ha)) {
8061da177e4SLinus Torvalds 		for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
8071da177e4SLinus Torvalds 		    rval == QLA_SUCCESS; cnt--) {
8081da177e4SLinus Torvalds 			if (cnt)
8091da177e4SLinus Torvalds 				udelay(100);
8101da177e4SLinus Torvalds 			else
8111da177e4SLinus Torvalds 				rval = QLA_FUNCTION_TIMEOUT;
8121da177e4SLinus Torvalds 		}
8131da177e4SLinus Torvalds 	}
8141da177e4SLinus Torvalds 
8151da177e4SLinus Torvalds 	/* Get RISC SRAM. */
816c5722708SAndrew Vasquez 	if (rval == QLA_SUCCESS)
817c5722708SAndrew Vasquez 		rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram,
818c5722708SAndrew Vasquez 		    sizeof(fw->risc_ram) / 2, &nxt);
8191da177e4SLinus Torvalds 
8201da177e4SLinus Torvalds 	/* Get stack SRAM. */
821c5722708SAndrew Vasquez 	if (rval == QLA_SUCCESS)
822c5722708SAndrew Vasquez 		rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram,
823c5722708SAndrew Vasquez 		    sizeof(fw->stack_ram) / 2, &nxt);
8241da177e4SLinus Torvalds 
8251da177e4SLinus Torvalds 	/* Get data SRAM. */
826c5722708SAndrew Vasquez 	if (rval == QLA_SUCCESS)
827c5722708SAndrew Vasquez 		rval = qla2xxx_dump_ram(ha, 0x11000, fw->data_ram,
828c5722708SAndrew Vasquez 		    ha->fw_memory_size - 0x11000 + 1, &nxt);
8291da177e4SLinus Torvalds 
830a7a167bfSAndrew Vasquez 	if (rval == QLA_SUCCESS)
83173208dfdSAnirban Chakraborty 		qla2xxx_copy_queues(ha, nxt);
832a7a167bfSAndrew Vasquez 
8333420d36cSAndrew Vasquez 	qla2xxx_dump_post_process(base_vha, rval);
8341da177e4SLinus Torvalds 
8351da177e4SLinus Torvalds qla2300_fw_dump_failed:
8361da177e4SLinus Torvalds 	if (!hardware_locked)
8371da177e4SLinus Torvalds 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
8381da177e4SLinus Torvalds }
8391da177e4SLinus Torvalds 
8401da177e4SLinus Torvalds /**
8411da177e4SLinus Torvalds  * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware.
8421da177e4SLinus Torvalds  * @ha: HA context
8431da177e4SLinus Torvalds  * @hardware_locked: Called with the hardware_lock
8441da177e4SLinus Torvalds  */
8451da177e4SLinus Torvalds void
8467b867cf7SAnirban Chakraborty qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
8471da177e4SLinus Torvalds {
8481da177e4SLinus Torvalds 	int		rval;
8491da177e4SLinus Torvalds 	uint32_t	cnt, timer;
8501da177e4SLinus Torvalds 	uint16_t	risc_address;
8511da177e4SLinus Torvalds 	uint16_t	mb0, mb2;
8527b867cf7SAnirban Chakraborty 	struct qla_hw_data *ha = vha->hw;
8533d71644cSAndrew Vasquez 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
8541da177e4SLinus Torvalds 	uint16_t __iomem *dmp_reg;
8551da177e4SLinus Torvalds 	unsigned long	flags;
8561da177e4SLinus Torvalds 	struct qla2100_fw_dump	*fw;
85773208dfdSAnirban Chakraborty 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
8581da177e4SLinus Torvalds 
8591da177e4SLinus Torvalds 	risc_address = 0;
8601da177e4SLinus Torvalds 	mb0 = mb2 = 0;
8611da177e4SLinus Torvalds 	flags = 0;
8621da177e4SLinus Torvalds 
8631da177e4SLinus Torvalds 	if (!hardware_locked)
8641da177e4SLinus Torvalds 		spin_lock_irqsave(&ha->hardware_lock, flags);
8651da177e4SLinus Torvalds 
866d4e3e04dSAndrew Vasquez 	if (!ha->fw_dump) {
8677c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd004,
8687c3df132SSaurav Kashyap 		    "No buffer available for dump.\n");
8691da177e4SLinus Torvalds 		goto qla2100_fw_dump_failed;
8701da177e4SLinus Torvalds 	}
8711da177e4SLinus Torvalds 
872d4e3e04dSAndrew Vasquez 	if (ha->fw_dumped) {
8737c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd005,
8747c3df132SSaurav Kashyap 		    "Firmware has been previously dumped (%p) "
8757c3df132SSaurav Kashyap 		    "-- ignoring request.\n",
8767c3df132SSaurav Kashyap 		    ha->fw_dump);
8771da177e4SLinus Torvalds 		goto qla2100_fw_dump_failed;
8781da177e4SLinus Torvalds 	}
879a7a167bfSAndrew Vasquez 	fw = &ha->fw_dump->isp.isp21;
880a7a167bfSAndrew Vasquez 	qla2xxx_prep_dump(ha, ha->fw_dump);
8811da177e4SLinus Torvalds 
8821da177e4SLinus Torvalds 	rval = QLA_SUCCESS;
883a7a167bfSAndrew Vasquez 	fw->hccr = htons(RD_REG_WORD(&reg->hccr));
8841da177e4SLinus Torvalds 
8851da177e4SLinus Torvalds 	/* Pause RISC. */
8861da177e4SLinus Torvalds 	WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
8871da177e4SLinus Torvalds 	for (cnt = 30000; (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
8881da177e4SLinus Torvalds 	    rval == QLA_SUCCESS; cnt--) {
8891da177e4SLinus Torvalds 		if (cnt)
8901da177e4SLinus Torvalds 			udelay(100);
8911da177e4SLinus Torvalds 		else
8921da177e4SLinus Torvalds 			rval = QLA_FUNCTION_TIMEOUT;
8931da177e4SLinus Torvalds 	}
8941da177e4SLinus Torvalds 	if (rval == QLA_SUCCESS) {
895c81d04c9SAndrew Vasquez 		dmp_reg = &reg->flash_address;
8961da177e4SLinus Torvalds 		for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
897a7a167bfSAndrew Vasquez 			fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
8981da177e4SLinus Torvalds 
899c81d04c9SAndrew Vasquez 		dmp_reg = &reg->u.isp2100.mailbox0;
9001da177e4SLinus Torvalds 		for (cnt = 0; cnt < ha->mbx_count; cnt++) {
901c81d04c9SAndrew Vasquez 			if (cnt == 8)
902c81d04c9SAndrew Vasquez 				dmp_reg = &reg->u_end.isp2200.mailbox8;
903c81d04c9SAndrew Vasquez 
904a7a167bfSAndrew Vasquez 			fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
9051da177e4SLinus Torvalds 		}
9061da177e4SLinus Torvalds 
907c81d04c9SAndrew Vasquez 		dmp_reg = &reg->u.isp2100.unused_2[0];
9081da177e4SLinus Torvalds 		for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++)
909a7a167bfSAndrew Vasquez 			fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
9101da177e4SLinus Torvalds 
9111da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, 0x00);
912c81d04c9SAndrew Vasquez 		dmp_reg = &reg->risc_hw;
9131da177e4SLinus Torvalds 		for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
914a7a167bfSAndrew Vasquez 			fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
9151da177e4SLinus Torvalds 
9161da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2000);
917c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);
9181da177e4SLinus Torvalds 
9191da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2100);
920c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);
9211da177e4SLinus Torvalds 
9221da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2200);
923c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);
9241da177e4SLinus Torvalds 
9251da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2300);
926c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);
9271da177e4SLinus Torvalds 
9281da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2400);
929c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);
9301da177e4SLinus Torvalds 
9311da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2500);
932c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);
9331da177e4SLinus Torvalds 
9341da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2600);
935c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);
9361da177e4SLinus Torvalds 
9371da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->pcr, 0x2700);
938c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);
9391da177e4SLinus Torvalds 
9401da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, 0x10);
941c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 16, fw->frame_buf_hdw_reg);
9421da177e4SLinus Torvalds 
9431da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, 0x20);
944c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);
9451da177e4SLinus Torvalds 
9461da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, 0x30);
947c81d04c9SAndrew Vasquez 		qla2xxx_read_window(reg, 64, fw->fpm_b1_reg);
9481da177e4SLinus Torvalds 
9491da177e4SLinus Torvalds 		/* Reset the ISP. */
9501da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
9511da177e4SLinus Torvalds 	}
9521da177e4SLinus Torvalds 
9531da177e4SLinus Torvalds 	for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
9541da177e4SLinus Torvalds 	    rval == QLA_SUCCESS; cnt--) {
9551da177e4SLinus Torvalds 		if (cnt)
9561da177e4SLinus Torvalds 			udelay(100);
9571da177e4SLinus Torvalds 		else
9581da177e4SLinus Torvalds 			rval = QLA_FUNCTION_TIMEOUT;
9591da177e4SLinus Torvalds 	}
9601da177e4SLinus Torvalds 
9611da177e4SLinus Torvalds 	/* Pause RISC. */
9621da177e4SLinus Torvalds 	if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) &&
9631da177e4SLinus Torvalds 	    (RD_REG_WORD(&reg->mctr) & (BIT_1 | BIT_0)) != 0))) {
9641da177e4SLinus Torvalds 
9651da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
9661da177e4SLinus Torvalds 		for (cnt = 30000;
9671da177e4SLinus Torvalds 		    (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
9681da177e4SLinus Torvalds 		    rval == QLA_SUCCESS; cnt--) {
9691da177e4SLinus Torvalds 			if (cnt)
9701da177e4SLinus Torvalds 				udelay(100);
9711da177e4SLinus Torvalds 			else
9721da177e4SLinus Torvalds 				rval = QLA_FUNCTION_TIMEOUT;
9731da177e4SLinus Torvalds 		}
9741da177e4SLinus Torvalds 		if (rval == QLA_SUCCESS) {
9751da177e4SLinus Torvalds 			/* Set memory configuration and timing. */
9761da177e4SLinus Torvalds 			if (IS_QLA2100(ha))
9771da177e4SLinus Torvalds 				WRT_REG_WORD(&reg->mctr, 0xf1);
9781da177e4SLinus Torvalds 			else
9791da177e4SLinus Torvalds 				WRT_REG_WORD(&reg->mctr, 0xf2);
9801da177e4SLinus Torvalds 			RD_REG_WORD(&reg->mctr);	/* PCI Posting. */
9811da177e4SLinus Torvalds 
9821da177e4SLinus Torvalds 			/* Release RISC. */
9831da177e4SLinus Torvalds 			WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
9841da177e4SLinus Torvalds 		}
9851da177e4SLinus Torvalds 	}
9861da177e4SLinus Torvalds 
9871da177e4SLinus Torvalds 	if (rval == QLA_SUCCESS) {
9881da177e4SLinus Torvalds 		/* Get RISC SRAM. */
9891da177e4SLinus Torvalds 		risc_address = 0x1000;
9901da177e4SLinus Torvalds  		WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
9911da177e4SLinus Torvalds 		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
9921da177e4SLinus Torvalds 	}
9931da177e4SLinus Torvalds 	for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;
9941da177e4SLinus Torvalds 	    cnt++, risc_address++) {
9951da177e4SLinus Torvalds  		WRT_MAILBOX_REG(ha, reg, 1, risc_address);
9961da177e4SLinus Torvalds 		WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
9971da177e4SLinus Torvalds 
9981da177e4SLinus Torvalds 		for (timer = 6000000; timer != 0; timer--) {
9991da177e4SLinus Torvalds 			/* Check for pending interrupts. */
10001da177e4SLinus Torvalds 			if (RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) {
10011da177e4SLinus Torvalds 				if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
10021da177e4SLinus Torvalds 					set_bit(MBX_INTERRUPT,
10031da177e4SLinus Torvalds 					    &ha->mbx_cmd_flags);
10041da177e4SLinus Torvalds 
10051da177e4SLinus Torvalds 					mb0 = RD_MAILBOX_REG(ha, reg, 0);
10061da177e4SLinus Torvalds 					mb2 = RD_MAILBOX_REG(ha, reg, 2);
10071da177e4SLinus Torvalds 
10081da177e4SLinus Torvalds 					WRT_REG_WORD(&reg->semaphore, 0);
10091da177e4SLinus Torvalds 					WRT_REG_WORD(&reg->hccr,
10101da177e4SLinus Torvalds 					    HCCR_CLR_RISC_INT);
10111da177e4SLinus Torvalds 					RD_REG_WORD(&reg->hccr);
10121da177e4SLinus Torvalds 					break;
10131da177e4SLinus Torvalds 				}
10141da177e4SLinus Torvalds 				WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
10151da177e4SLinus Torvalds 				RD_REG_WORD(&reg->hccr);
10161da177e4SLinus Torvalds 			}
10171da177e4SLinus Torvalds 			udelay(5);
10181da177e4SLinus Torvalds 		}
10191da177e4SLinus Torvalds 
10201da177e4SLinus Torvalds 		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
10211da177e4SLinus Torvalds 			rval = mb0 & MBS_MASK;
1022a7a167bfSAndrew Vasquez 			fw->risc_ram[cnt] = htons(mb2);
10231da177e4SLinus Torvalds 		} else {
10241da177e4SLinus Torvalds 			rval = QLA_FUNCTION_FAILED;
10251da177e4SLinus Torvalds 		}
10261da177e4SLinus Torvalds 	}
10271da177e4SLinus Torvalds 
1028a7a167bfSAndrew Vasquez 	if (rval == QLA_SUCCESS)
102973208dfdSAnirban Chakraborty 		qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);
1030a7a167bfSAndrew Vasquez 
10313420d36cSAndrew Vasquez 	qla2xxx_dump_post_process(base_vha, rval);
10321da177e4SLinus Torvalds 
10331da177e4SLinus Torvalds qla2100_fw_dump_failed:
10341da177e4SLinus Torvalds 	if (!hardware_locked)
10351da177e4SLinus Torvalds 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
10361da177e4SLinus Torvalds }
10371da177e4SLinus Torvalds 
10386d9b61edSAndrew Vasquez void
10397b867cf7SAnirban Chakraborty qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
10406d9b61edSAndrew Vasquez {
10416d9b61edSAndrew Vasquez 	int		rval;
1042c3a2f0dfSAndrew Vasquez 	uint32_t	cnt;
10436d9b61edSAndrew Vasquez 	uint32_t	risc_address;
10447b867cf7SAnirban Chakraborty 	struct qla_hw_data *ha = vha->hw;
10456d9b61edSAndrew Vasquez 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
10466d9b61edSAndrew Vasquez 	uint32_t __iomem *dmp_reg;
10476d9b61edSAndrew Vasquez 	uint32_t	*iter_reg;
10486d9b61edSAndrew Vasquez 	uint16_t __iomem *mbx_reg;
10496d9b61edSAndrew Vasquez 	unsigned long	flags;
10506d9b61edSAndrew Vasquez 	struct qla24xx_fw_dump *fw;
10516d9b61edSAndrew Vasquez 	uint32_t	ext_mem_cnt;
1052c3a2f0dfSAndrew Vasquez 	void		*nxt;
10532d70c103SNicholas Bellinger 	void		*nxt_chain;
10542d70c103SNicholas Bellinger 	uint32_t	*last_chain = NULL;
105573208dfdSAnirban Chakraborty 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
10566d9b61edSAndrew Vasquez 
10577ec0effdSAtul Deshmukh 	if (IS_P3P_TYPE(ha))
1058a9083016SGiridhar Malavali 		return;
1059a9083016SGiridhar Malavali 
10606d9b61edSAndrew Vasquez 	risc_address = ext_mem_cnt = 0;
10616d9b61edSAndrew Vasquez 	flags = 0;
106261f098ddSHiral Patel 	ha->fw_dump_cap_flags = 0;
10636d9b61edSAndrew Vasquez 
10646d9b61edSAndrew Vasquez 	if (!hardware_locked)
10656d9b61edSAndrew Vasquez 		spin_lock_irqsave(&ha->hardware_lock, flags);
10666d9b61edSAndrew Vasquez 
1067d4e3e04dSAndrew Vasquez 	if (!ha->fw_dump) {
10687c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd006,
10697c3df132SSaurav Kashyap 		    "No buffer available for dump.\n");
10706d9b61edSAndrew Vasquez 		goto qla24xx_fw_dump_failed;
10716d9b61edSAndrew Vasquez 	}
10726d9b61edSAndrew Vasquez 
10736d9b61edSAndrew Vasquez 	if (ha->fw_dumped) {
10747c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd007,
10757c3df132SSaurav Kashyap 		    "Firmware has been previously dumped (%p) "
10767c3df132SSaurav Kashyap 		    "-- ignoring request.\n",
10777c3df132SSaurav Kashyap 		    ha->fw_dump);
10786d9b61edSAndrew Vasquez 		goto qla24xx_fw_dump_failed;
10796d9b61edSAndrew Vasquez 	}
1080a7a167bfSAndrew Vasquez 	fw = &ha->fw_dump->isp.isp24;
1081a7a167bfSAndrew Vasquez 	qla2xxx_prep_dump(ha, ha->fw_dump);
10826d9b61edSAndrew Vasquez 
1083a7a167bfSAndrew Vasquez 	fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
10846d9b61edSAndrew Vasquez 
10852f389fc4SHiral Patel 	/*
10862f389fc4SHiral Patel 	 * Pause RISC. No need to track timeout, as resetting the chip
10872f389fc4SHiral Patel 	 * is the right approach incase of pause timeout
10882f389fc4SHiral Patel 	 */
108961f098ddSHiral Patel 	qla24xx_pause_risc(reg, ha);
10906d9b61edSAndrew Vasquez 
10916d9b61edSAndrew Vasquez 	/* Host interface registers. */
1092c81d04c9SAndrew Vasquez 	dmp_reg = &reg->flash_addr;
10936d9b61edSAndrew Vasquez 	for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
1094a7a167bfSAndrew Vasquez 		fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
10956d9b61edSAndrew Vasquez 
1096210d5350Sandrew.vasquez@qlogic.com 	/* Disable interrupts. */
1097210d5350Sandrew.vasquez@qlogic.com 	WRT_REG_DWORD(&reg->ictrl, 0);
1098210d5350Sandrew.vasquez@qlogic.com 	RD_REG_DWORD(&reg->ictrl);
1099210d5350Sandrew.vasquez@qlogic.com 
1100210d5350Sandrew.vasquez@qlogic.com 	/* Shadow registers. */
1101210d5350Sandrew.vasquez@qlogic.com 	WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1102210d5350Sandrew.vasquez@qlogic.com 	RD_REG_DWORD(&reg->iobase_addr);
1103c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
1104c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1105210d5350Sandrew.vasquez@qlogic.com 
1106c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
1107c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1108210d5350Sandrew.vasquez@qlogic.com 
1109c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
1110c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1111210d5350Sandrew.vasquez@qlogic.com 
1112c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
1113c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1114210d5350Sandrew.vasquez@qlogic.com 
1115c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
1116c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1117210d5350Sandrew.vasquez@qlogic.com 
1118c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
1119c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1120210d5350Sandrew.vasquez@qlogic.com 
1121c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
1122c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1123210d5350Sandrew.vasquez@qlogic.com 
11246d9b61edSAndrew Vasquez 	/* Mailbox registers. */
1125c3a2f0dfSAndrew Vasquez 	mbx_reg = &reg->mailbox0;
11266d9b61edSAndrew Vasquez 	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
1127a7a167bfSAndrew Vasquez 		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
11286d9b61edSAndrew Vasquez 
11296d9b61edSAndrew Vasquez 	/* Transfer sequence registers. */
11306d9b61edSAndrew Vasquez 	iter_reg = fw->xseq_gp_reg;
1131c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1132c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1133c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1134c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1135c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1136c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1137c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1138c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
11396d9b61edSAndrew Vasquez 
1140c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xBFE0, 16, fw->xseq_0_reg);
1141c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
11426d9b61edSAndrew Vasquez 
11436d9b61edSAndrew Vasquez 	/* Receive sequence registers. */
11446d9b61edSAndrew Vasquez 	iter_reg = fw->rseq_gp_reg;
1145c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1146c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1147c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1148c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1149c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1150c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1151c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1152c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
11536d9b61edSAndrew Vasquez 
1154c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xFFD0, 16, fw->rseq_0_reg);
1155c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1156c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
11576d9b61edSAndrew Vasquez 
11586d9b61edSAndrew Vasquez 	/* Command DMA registers. */
1159c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
11606d9b61edSAndrew Vasquez 
11616d9b61edSAndrew Vasquez 	/* Queues. */
11626d9b61edSAndrew Vasquez 	iter_reg = fw->req0_dma_reg;
1163c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1164c3a2f0dfSAndrew Vasquez 	dmp_reg = &reg->iobase_q;
11656d9b61edSAndrew Vasquez 	for (cnt = 0; cnt < 7; cnt++)
1166a7a167bfSAndrew Vasquez 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
11676d9b61edSAndrew Vasquez 
11686d9b61edSAndrew Vasquez 	iter_reg = fw->resp0_dma_reg;
1169c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1170c3a2f0dfSAndrew Vasquez 	dmp_reg = &reg->iobase_q;
11716d9b61edSAndrew Vasquez 	for (cnt = 0; cnt < 7; cnt++)
1172a7a167bfSAndrew Vasquez 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
11736d9b61edSAndrew Vasquez 
11746d9b61edSAndrew Vasquez 	iter_reg = fw->req1_dma_reg;
1175c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1176c3a2f0dfSAndrew Vasquez 	dmp_reg = &reg->iobase_q;
11776d9b61edSAndrew Vasquez 	for (cnt = 0; cnt < 7; cnt++)
1178a7a167bfSAndrew Vasquez 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
11796d9b61edSAndrew Vasquez 
11806d9b61edSAndrew Vasquez 	/* Transmit DMA registers. */
11816d9b61edSAndrew Vasquez 	iter_reg = fw->xmt0_dma_reg;
1182c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1183c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7610, 16, iter_reg);
11846d9b61edSAndrew Vasquez 
11856d9b61edSAndrew Vasquez 	iter_reg = fw->xmt1_dma_reg;
1186c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1187c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7630, 16, iter_reg);
11886d9b61edSAndrew Vasquez 
11896d9b61edSAndrew Vasquez 	iter_reg = fw->xmt2_dma_reg;
1190c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1191c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7650, 16, iter_reg);
11926d9b61edSAndrew Vasquez 
11936d9b61edSAndrew Vasquez 	iter_reg = fw->xmt3_dma_reg;
1194c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1195c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7670, 16, iter_reg);
11966d9b61edSAndrew Vasquez 
11976d9b61edSAndrew Vasquez 	iter_reg = fw->xmt4_dma_reg;
1198c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1199c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7690, 16, iter_reg);
12006d9b61edSAndrew Vasquez 
1201c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
12026d9b61edSAndrew Vasquez 
12036d9b61edSAndrew Vasquez 	/* Receive DMA registers. */
12046d9b61edSAndrew Vasquez 	iter_reg = fw->rcvt0_data_dma_reg;
1205c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1206c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7710, 16, iter_reg);
12076d9b61edSAndrew Vasquez 
12086d9b61edSAndrew Vasquez 	iter_reg = fw->rcvt1_data_dma_reg;
1209c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1210c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7730, 16, iter_reg);
12116d9b61edSAndrew Vasquez 
12126d9b61edSAndrew Vasquez 	/* RISC registers. */
12136d9b61edSAndrew Vasquez 	iter_reg = fw->risc_gp_reg;
1214c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1215c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1216c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1217c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1218c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1219c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1220c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1221c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
12226d9b61edSAndrew Vasquez 
12236d9b61edSAndrew Vasquez 	/* Local memory controller registers. */
12246d9b61edSAndrew Vasquez 	iter_reg = fw->lmc_reg;
1225c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1226c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1227c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1228c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1229c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1230c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1231c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x3060, 16, iter_reg);
12326d9b61edSAndrew Vasquez 
12336d9b61edSAndrew Vasquez 	/* Fibre Protocol Module registers. */
12346d9b61edSAndrew Vasquez 	iter_reg = fw->fpm_hdw_reg;
1235c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1236c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1237c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1238c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1239c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1240c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1241c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1242c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1243c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1244c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1245c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1246c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
12476d9b61edSAndrew Vasquez 
12486d9b61edSAndrew Vasquez 	/* Frame Buffer registers. */
12496d9b61edSAndrew Vasquez 	iter_reg = fw->fb_hdw_reg;
1250c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1251c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1252c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1253c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1254c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1255c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1256c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1257c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1258c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1259c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1260c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
12616d9b61edSAndrew Vasquez 
1262c81d04c9SAndrew Vasquez 	rval = qla24xx_soft_reset(ha);
1263c81d04c9SAndrew Vasquez 	if (rval != QLA_SUCCESS)
1264c81d04c9SAndrew Vasquez 		goto qla24xx_fw_dump_failed_0;
12656d9b61edSAndrew Vasquez 
1266c81d04c9SAndrew Vasquez 	rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
1267c5722708SAndrew Vasquez 	    &nxt);
1268c81d04c9SAndrew Vasquez 	if (rval != QLA_SUCCESS)
1269c81d04c9SAndrew Vasquez 		goto qla24xx_fw_dump_failed_0;
12706d9b61edSAndrew Vasquez 
127173208dfdSAnirban Chakraborty 	nxt = qla2xxx_copy_queues(ha, nxt);
1272bb99de67SAndrew Vasquez 
1273bb99de67SAndrew Vasquez 	qla24xx_copy_eft(ha, nxt);
1274a7a167bfSAndrew Vasquez 
12752d70c103SNicholas Bellinger 	nxt_chain = (void *)ha->fw_dump + ha->chain_offset;
12762d70c103SNicholas Bellinger 	nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
12772d70c103SNicholas Bellinger 	if (last_chain) {
12782d70c103SNicholas Bellinger 		ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
12792d70c103SNicholas Bellinger 		*last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
12802d70c103SNicholas Bellinger 	}
12812d70c103SNicholas Bellinger 
12822d70c103SNicholas Bellinger 	/* Adjust valid length. */
12832d70c103SNicholas Bellinger 	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
12842d70c103SNicholas Bellinger 
1285c81d04c9SAndrew Vasquez qla24xx_fw_dump_failed_0:
12863420d36cSAndrew Vasquez 	qla2xxx_dump_post_process(base_vha, rval);
12876d9b61edSAndrew Vasquez 
12886d9b61edSAndrew Vasquez qla24xx_fw_dump_failed:
12896d9b61edSAndrew Vasquez 	if (!hardware_locked)
12906d9b61edSAndrew Vasquez 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
12916d9b61edSAndrew Vasquez }
12926d9b61edSAndrew Vasquez 
1293c3a2f0dfSAndrew Vasquez void
12947b867cf7SAnirban Chakraborty qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
1295c3a2f0dfSAndrew Vasquez {
1296c3a2f0dfSAndrew Vasquez 	int		rval;
1297c3a2f0dfSAndrew Vasquez 	uint32_t	cnt;
1298c3a2f0dfSAndrew Vasquez 	uint32_t	risc_address;
12997b867cf7SAnirban Chakraborty 	struct qla_hw_data *ha = vha->hw;
1300c3a2f0dfSAndrew Vasquez 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1301c3a2f0dfSAndrew Vasquez 	uint32_t __iomem *dmp_reg;
1302c3a2f0dfSAndrew Vasquez 	uint32_t	*iter_reg;
1303c3a2f0dfSAndrew Vasquez 	uint16_t __iomem *mbx_reg;
1304c3a2f0dfSAndrew Vasquez 	unsigned long	flags;
1305c3a2f0dfSAndrew Vasquez 	struct qla25xx_fw_dump *fw;
1306c3a2f0dfSAndrew Vasquez 	uint32_t	ext_mem_cnt;
1307d63ab533SAndrew Vasquez 	void		*nxt, *nxt_chain;
1308bb99de67SAndrew Vasquez 	uint32_t	*last_chain = NULL;
130973208dfdSAnirban Chakraborty 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
1310c3a2f0dfSAndrew Vasquez 
1311c3a2f0dfSAndrew Vasquez 	risc_address = ext_mem_cnt = 0;
1312c3a2f0dfSAndrew Vasquez 	flags = 0;
131361f098ddSHiral Patel 	ha->fw_dump_cap_flags = 0;
1314c3a2f0dfSAndrew Vasquez 
1315c3a2f0dfSAndrew Vasquez 	if (!hardware_locked)
1316c3a2f0dfSAndrew Vasquez 		spin_lock_irqsave(&ha->hardware_lock, flags);
1317c3a2f0dfSAndrew Vasquez 
1318c3a2f0dfSAndrew Vasquez 	if (!ha->fw_dump) {
13197c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd008,
13207c3df132SSaurav Kashyap 		    "No buffer available for dump.\n");
1321c3a2f0dfSAndrew Vasquez 		goto qla25xx_fw_dump_failed;
1322c3a2f0dfSAndrew Vasquez 	}
1323c3a2f0dfSAndrew Vasquez 
1324c3a2f0dfSAndrew Vasquez 	if (ha->fw_dumped) {
13257c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd009,
13267c3df132SSaurav Kashyap 		    "Firmware has been previously dumped (%p) "
13277c3df132SSaurav Kashyap 		    "-- ignoring request.\n",
13287c3df132SSaurav Kashyap 		    ha->fw_dump);
1329c3a2f0dfSAndrew Vasquez 		goto qla25xx_fw_dump_failed;
1330c3a2f0dfSAndrew Vasquez 	}
1331c3a2f0dfSAndrew Vasquez 	fw = &ha->fw_dump->isp.isp25;
1332c3a2f0dfSAndrew Vasquez 	qla2xxx_prep_dump(ha, ha->fw_dump);
1333b5836927SAndrew Vasquez 	ha->fw_dump->version = __constant_htonl(2);
1334c3a2f0dfSAndrew Vasquez 
1335c3a2f0dfSAndrew Vasquez 	fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
1336c3a2f0dfSAndrew Vasquez 
13372f389fc4SHiral Patel 	/*
13382f389fc4SHiral Patel 	 * Pause RISC. No need to track timeout, as resetting the chip
13392f389fc4SHiral Patel 	 * is the right approach incase of pause timeout
13402f389fc4SHiral Patel 	 */
134161f098ddSHiral Patel 	qla24xx_pause_risc(reg, ha);
1342c3a2f0dfSAndrew Vasquez 
1343b5836927SAndrew Vasquez 	/* Host/Risc registers. */
1344b5836927SAndrew Vasquez 	iter_reg = fw->host_risc_reg;
1345b5836927SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
1346b5836927SAndrew Vasquez 	qla24xx_read_window(reg, 0x7010, 16, iter_reg);
1347b5836927SAndrew Vasquez 
1348b5836927SAndrew Vasquez 	/* PCIe registers. */
1349b5836927SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
1350b5836927SAndrew Vasquez 	RD_REG_DWORD(&reg->iobase_addr);
1351b5836927SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_window, 0x01);
1352b5836927SAndrew Vasquez 	dmp_reg = &reg->iobase_c4;
1353b5836927SAndrew Vasquez 	fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++));
1354b5836927SAndrew Vasquez 	fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
1355b5836927SAndrew Vasquez 	fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
1356b5836927SAndrew Vasquez 	fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
135773208dfdSAnirban Chakraborty 
1358b5836927SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_window, 0x00);
1359b5836927SAndrew Vasquez 	RD_REG_DWORD(&reg->iobase_window);
1360b5836927SAndrew Vasquez 
1361c3a2f0dfSAndrew Vasquez 	/* Host interface registers. */
1362c81d04c9SAndrew Vasquez 	dmp_reg = &reg->flash_addr;
1363c3a2f0dfSAndrew Vasquez 	for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
1364c3a2f0dfSAndrew Vasquez 		fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
1365c3a2f0dfSAndrew Vasquez 
1366c3a2f0dfSAndrew Vasquez 	/* Disable interrupts. */
1367c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->ictrl, 0);
1368c3a2f0dfSAndrew Vasquez 	RD_REG_DWORD(&reg->ictrl);
1369c3a2f0dfSAndrew Vasquez 
1370c3a2f0dfSAndrew Vasquez 	/* Shadow registers. */
1371c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1372c3a2f0dfSAndrew Vasquez 	RD_REG_DWORD(&reg->iobase_addr);
1373c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
1374c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1375c3a2f0dfSAndrew Vasquez 
1376c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
1377c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1378c3a2f0dfSAndrew Vasquez 
1379c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
1380c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1381c3a2f0dfSAndrew Vasquez 
1382c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
1383c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1384c3a2f0dfSAndrew Vasquez 
1385c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
1386c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1387c3a2f0dfSAndrew Vasquez 
1388c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
1389c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1390c3a2f0dfSAndrew Vasquez 
1391c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
1392c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1393c3a2f0dfSAndrew Vasquez 
1394c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
1395c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1396c3a2f0dfSAndrew Vasquez 
1397c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
1398c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1399c3a2f0dfSAndrew Vasquez 
1400c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
1401c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1402c3a2f0dfSAndrew Vasquez 
1403c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
1404c3a2f0dfSAndrew Vasquez 	fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1405c3a2f0dfSAndrew Vasquez 
1406c3a2f0dfSAndrew Vasquez 	/* RISC I/O register. */
1407c3a2f0dfSAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
1408c3a2f0dfSAndrew Vasquez 	fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
1409c3a2f0dfSAndrew Vasquez 
1410c3a2f0dfSAndrew Vasquez 	/* Mailbox registers. */
1411c3a2f0dfSAndrew Vasquez 	mbx_reg = &reg->mailbox0;
1412c3a2f0dfSAndrew Vasquez 	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
1413c3a2f0dfSAndrew Vasquez 		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
1414c3a2f0dfSAndrew Vasquez 
1415c3a2f0dfSAndrew Vasquez 	/* Transfer sequence registers. */
1416c3a2f0dfSAndrew Vasquez 	iter_reg = fw->xseq_gp_reg;
1417c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1418c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1419c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1420c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1421c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1422c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1423c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1424c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
1425c3a2f0dfSAndrew Vasquez 
1426c3a2f0dfSAndrew Vasquez 	iter_reg = fw->xseq_0_reg;
1427c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
1428c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
1429c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
1430c3a2f0dfSAndrew Vasquez 
1431c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
1432c3a2f0dfSAndrew Vasquez 
1433c3a2f0dfSAndrew Vasquez 	/* Receive sequence registers. */
1434c3a2f0dfSAndrew Vasquez 	iter_reg = fw->rseq_gp_reg;
1435c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1436c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1437c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1438c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1439c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1440c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1441c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1442c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
1443c3a2f0dfSAndrew Vasquez 
1444c3a2f0dfSAndrew Vasquez 	iter_reg = fw->rseq_0_reg;
1445c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
1446c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
1447c3a2f0dfSAndrew Vasquez 
1448c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1449c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
1450c3a2f0dfSAndrew Vasquez 
1451c3a2f0dfSAndrew Vasquez 	/* Auxiliary sequence registers. */
1452c3a2f0dfSAndrew Vasquez 	iter_reg = fw->aseq_gp_reg;
1453c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
1454c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
1455c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
1456c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
1457c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
1458c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
1459c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
1460c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xB070, 16, iter_reg);
1461c3a2f0dfSAndrew Vasquez 
1462c3a2f0dfSAndrew Vasquez 	iter_reg = fw->aseq_0_reg;
1463c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
1464c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
1465c3a2f0dfSAndrew Vasquez 
1466c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
1467c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
1468c3a2f0dfSAndrew Vasquez 
1469c3a2f0dfSAndrew Vasquez 	/* Command DMA registers. */
1470c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
1471c3a2f0dfSAndrew Vasquez 
1472c3a2f0dfSAndrew Vasquez 	/* Queues. */
1473c3a2f0dfSAndrew Vasquez 	iter_reg = fw->req0_dma_reg;
1474c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1475c3a2f0dfSAndrew Vasquez 	dmp_reg = &reg->iobase_q;
1476c3a2f0dfSAndrew Vasquez 	for (cnt = 0; cnt < 7; cnt++)
1477c3a2f0dfSAndrew Vasquez 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
1478c3a2f0dfSAndrew Vasquez 
1479c3a2f0dfSAndrew Vasquez 	iter_reg = fw->resp0_dma_reg;
1480c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1481c3a2f0dfSAndrew Vasquez 	dmp_reg = &reg->iobase_q;
1482c3a2f0dfSAndrew Vasquez 	for (cnt = 0; cnt < 7; cnt++)
1483c3a2f0dfSAndrew Vasquez 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
1484c3a2f0dfSAndrew Vasquez 
1485c3a2f0dfSAndrew Vasquez 	iter_reg = fw->req1_dma_reg;
1486c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1487c3a2f0dfSAndrew Vasquez 	dmp_reg = &reg->iobase_q;
1488c3a2f0dfSAndrew Vasquez 	for (cnt = 0; cnt < 7; cnt++)
1489c3a2f0dfSAndrew Vasquez 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
1490c3a2f0dfSAndrew Vasquez 
1491c3a2f0dfSAndrew Vasquez 	/* Transmit DMA registers. */
1492c3a2f0dfSAndrew Vasquez 	iter_reg = fw->xmt0_dma_reg;
1493c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1494c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7610, 16, iter_reg);
1495c3a2f0dfSAndrew Vasquez 
1496c3a2f0dfSAndrew Vasquez 	iter_reg = fw->xmt1_dma_reg;
1497c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1498c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7630, 16, iter_reg);
1499c3a2f0dfSAndrew Vasquez 
1500c3a2f0dfSAndrew Vasquez 	iter_reg = fw->xmt2_dma_reg;
1501c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1502c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7650, 16, iter_reg);
1503c3a2f0dfSAndrew Vasquez 
1504c3a2f0dfSAndrew Vasquez 	iter_reg = fw->xmt3_dma_reg;
1505c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1506c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7670, 16, iter_reg);
1507c3a2f0dfSAndrew Vasquez 
1508c3a2f0dfSAndrew Vasquez 	iter_reg = fw->xmt4_dma_reg;
1509c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1510c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7690, 16, iter_reg);
1511c3a2f0dfSAndrew Vasquez 
1512c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
1513c3a2f0dfSAndrew Vasquez 
1514c3a2f0dfSAndrew Vasquez 	/* Receive DMA registers. */
1515c3a2f0dfSAndrew Vasquez 	iter_reg = fw->rcvt0_data_dma_reg;
1516c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1517c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7710, 16, iter_reg);
1518c3a2f0dfSAndrew Vasquez 
1519c3a2f0dfSAndrew Vasquez 	iter_reg = fw->rcvt1_data_dma_reg;
1520c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1521c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x7730, 16, iter_reg);
1522c3a2f0dfSAndrew Vasquez 
1523c3a2f0dfSAndrew Vasquez 	/* RISC registers. */
1524c3a2f0dfSAndrew Vasquez 	iter_reg = fw->risc_gp_reg;
1525c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1526c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1527c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1528c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1529c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1530c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1531c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1532c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
1533c3a2f0dfSAndrew Vasquez 
1534c3a2f0dfSAndrew Vasquez 	/* Local memory controller registers. */
1535c3a2f0dfSAndrew Vasquez 	iter_reg = fw->lmc_reg;
1536c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1537c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1538c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1539c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1540c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1541c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1542c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
1543c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x3070, 16, iter_reg);
1544c3a2f0dfSAndrew Vasquez 
1545c3a2f0dfSAndrew Vasquez 	/* Fibre Protocol Module registers. */
1546c3a2f0dfSAndrew Vasquez 	iter_reg = fw->fpm_hdw_reg;
1547c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1548c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1549c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1550c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1551c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1552c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1553c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1554c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1555c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1556c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1557c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1558c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
1559c3a2f0dfSAndrew Vasquez 
1560c3a2f0dfSAndrew Vasquez 	/* Frame Buffer registers. */
1561c3a2f0dfSAndrew Vasquez 	iter_reg = fw->fb_hdw_reg;
1562c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1563c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1564c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1565c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1566c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1567c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1568c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1569c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1570c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1571c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1572c81d04c9SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
1573c81d04c9SAndrew Vasquez 	qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
1574c3a2f0dfSAndrew Vasquez 
1575d63ab533SAndrew Vasquez 	/* Multi queue registers */
1576d63ab533SAndrew Vasquez 	nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
1577d63ab533SAndrew Vasquez 	    &last_chain);
1578d63ab533SAndrew Vasquez 
1579c81d04c9SAndrew Vasquez 	rval = qla24xx_soft_reset(ha);
1580c81d04c9SAndrew Vasquez 	if (rval != QLA_SUCCESS)
1581c81d04c9SAndrew Vasquez 		goto qla25xx_fw_dump_failed_0;
1582c3a2f0dfSAndrew Vasquez 
1583c81d04c9SAndrew Vasquez 	rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
1584c5722708SAndrew Vasquez 	    &nxt);
1585c81d04c9SAndrew Vasquez 	if (rval != QLA_SUCCESS)
1586c81d04c9SAndrew Vasquez 		goto qla25xx_fw_dump_failed_0;
1587c3a2f0dfSAndrew Vasquez 
158873208dfdSAnirban Chakraborty 	nxt = qla2xxx_copy_queues(ha, nxt);
1589c3a2f0dfSAndrew Vasquez 
15907f544d00SBart Van Assche 	qla24xx_copy_eft(ha, nxt);
1591df613b96SAndrew Vasquez 
1592d63ab533SAndrew Vasquez 	/* Chain entries -- started with MQ. */
1593050c9bb1SGiridhar Malavali 	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
1594050c9bb1SGiridhar Malavali 	nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
15952d70c103SNicholas Bellinger 	nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
1596bb99de67SAndrew Vasquez 	if (last_chain) {
1597bb99de67SAndrew Vasquez 		ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
1598bb99de67SAndrew Vasquez 		*last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
1599bb99de67SAndrew Vasquez 	}
1600df613b96SAndrew Vasquez 
1601050c9bb1SGiridhar Malavali 	/* Adjust valid length. */
1602050c9bb1SGiridhar Malavali 	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1603050c9bb1SGiridhar Malavali 
1604c81d04c9SAndrew Vasquez qla25xx_fw_dump_failed_0:
16053420d36cSAndrew Vasquez 	qla2xxx_dump_post_process(base_vha, rval);
1606c3a2f0dfSAndrew Vasquez 
1607c3a2f0dfSAndrew Vasquez qla25xx_fw_dump_failed:
1608c3a2f0dfSAndrew Vasquez 	if (!hardware_locked)
1609c3a2f0dfSAndrew Vasquez 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
1610c3a2f0dfSAndrew Vasquez }
16113a03eb79SAndrew Vasquez 
16123a03eb79SAndrew Vasquez void
16133a03eb79SAndrew Vasquez qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
16143a03eb79SAndrew Vasquez {
16153a03eb79SAndrew Vasquez 	int		rval;
16163a03eb79SAndrew Vasquez 	uint32_t	cnt;
16173a03eb79SAndrew Vasquez 	uint32_t	risc_address;
16183a03eb79SAndrew Vasquez 	struct qla_hw_data *ha = vha->hw;
16193a03eb79SAndrew Vasquez 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
16203a03eb79SAndrew Vasquez 	uint32_t __iomem *dmp_reg;
16213a03eb79SAndrew Vasquez 	uint32_t	*iter_reg;
16223a03eb79SAndrew Vasquez 	uint16_t __iomem *mbx_reg;
16233a03eb79SAndrew Vasquez 	unsigned long	flags;
16243a03eb79SAndrew Vasquez 	struct qla81xx_fw_dump *fw;
16253a03eb79SAndrew Vasquez 	uint32_t	ext_mem_cnt;
16263a03eb79SAndrew Vasquez 	void		*nxt, *nxt_chain;
16273a03eb79SAndrew Vasquez 	uint32_t	*last_chain = NULL;
16283a03eb79SAndrew Vasquez 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
16293a03eb79SAndrew Vasquez 
16303a03eb79SAndrew Vasquez 	risc_address = ext_mem_cnt = 0;
16313a03eb79SAndrew Vasquez 	flags = 0;
163261f098ddSHiral Patel 	ha->fw_dump_cap_flags = 0;
16333a03eb79SAndrew Vasquez 
16343a03eb79SAndrew Vasquez 	if (!hardware_locked)
16353a03eb79SAndrew Vasquez 		spin_lock_irqsave(&ha->hardware_lock, flags);
16363a03eb79SAndrew Vasquez 
16373a03eb79SAndrew Vasquez 	if (!ha->fw_dump) {
16387c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd00a,
16397c3df132SSaurav Kashyap 		    "No buffer available for dump.\n");
16403a03eb79SAndrew Vasquez 		goto qla81xx_fw_dump_failed;
16413a03eb79SAndrew Vasquez 	}
16423a03eb79SAndrew Vasquez 
16433a03eb79SAndrew Vasquez 	if (ha->fw_dumped) {
16447c3df132SSaurav Kashyap 		ql_log(ql_log_warn, vha, 0xd00b,
16457c3df132SSaurav Kashyap 		    "Firmware has been previously dumped (%p) "
16467c3df132SSaurav Kashyap 		    "-- ignoring request.\n",
16477c3df132SSaurav Kashyap 		    ha->fw_dump);
16483a03eb79SAndrew Vasquez 		goto qla81xx_fw_dump_failed;
16493a03eb79SAndrew Vasquez 	}
16503a03eb79SAndrew Vasquez 	fw = &ha->fw_dump->isp.isp81;
16513a03eb79SAndrew Vasquez 	qla2xxx_prep_dump(ha, ha->fw_dump);
16523a03eb79SAndrew Vasquez 
16533a03eb79SAndrew Vasquez 	fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
16543a03eb79SAndrew Vasquez 
16552f389fc4SHiral Patel 	/*
16562f389fc4SHiral Patel 	 * Pause RISC. No need to track timeout, as resetting the chip
16572f389fc4SHiral Patel 	 * is the right approach incase of pause timeout
16582f389fc4SHiral Patel 	 */
165961f098ddSHiral Patel 	qla24xx_pause_risc(reg, ha);
16603a03eb79SAndrew Vasquez 
16613a03eb79SAndrew Vasquez 	/* Host/Risc registers. */
16623a03eb79SAndrew Vasquez 	iter_reg = fw->host_risc_reg;
16633a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
16643a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x7010, 16, iter_reg);
16653a03eb79SAndrew Vasquez 
16663a03eb79SAndrew Vasquez 	/* PCIe registers. */
16673a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
16683a03eb79SAndrew Vasquez 	RD_REG_DWORD(&reg->iobase_addr);
16693a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_window, 0x01);
16703a03eb79SAndrew Vasquez 	dmp_reg = &reg->iobase_c4;
16713a03eb79SAndrew Vasquez 	fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++));
16723a03eb79SAndrew Vasquez 	fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
16733a03eb79SAndrew Vasquez 	fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
16743a03eb79SAndrew Vasquez 	fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
16753a03eb79SAndrew Vasquez 
16763a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_window, 0x00);
16773a03eb79SAndrew Vasquez 	RD_REG_DWORD(&reg->iobase_window);
16783a03eb79SAndrew Vasquez 
16793a03eb79SAndrew Vasquez 	/* Host interface registers. */
16803a03eb79SAndrew Vasquez 	dmp_reg = &reg->flash_addr;
16813a03eb79SAndrew Vasquez 	for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
16823a03eb79SAndrew Vasquez 		fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
16833a03eb79SAndrew Vasquez 
16843a03eb79SAndrew Vasquez 	/* Disable interrupts. */
16853a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->ictrl, 0);
16863a03eb79SAndrew Vasquez 	RD_REG_DWORD(&reg->ictrl);
16873a03eb79SAndrew Vasquez 
16883a03eb79SAndrew Vasquez 	/* Shadow registers. */
16893a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
16903a03eb79SAndrew Vasquez 	RD_REG_DWORD(&reg->iobase_addr);
16913a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
16923a03eb79SAndrew Vasquez 	fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
16933a03eb79SAndrew Vasquez 
16943a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
16953a03eb79SAndrew Vasquez 	fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
16963a03eb79SAndrew Vasquez 
16973a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
16983a03eb79SAndrew Vasquez 	fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
16993a03eb79SAndrew Vasquez 
17003a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
17013a03eb79SAndrew Vasquez 	fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
17023a03eb79SAndrew Vasquez 
17033a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
17043a03eb79SAndrew Vasquez 	fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
17053a03eb79SAndrew Vasquez 
17063a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
17073a03eb79SAndrew Vasquez 	fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
17083a03eb79SAndrew Vasquez 
17093a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
17103a03eb79SAndrew Vasquez 	fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
17113a03eb79SAndrew Vasquez 
17123a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
17133a03eb79SAndrew Vasquez 	fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
17143a03eb79SAndrew Vasquez 
17153a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
17163a03eb79SAndrew Vasquez 	fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
17173a03eb79SAndrew Vasquez 
17183a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
17193a03eb79SAndrew Vasquez 	fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
17203a03eb79SAndrew Vasquez 
17213a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
17223a03eb79SAndrew Vasquez 	fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
17233a03eb79SAndrew Vasquez 
17243a03eb79SAndrew Vasquez 	/* RISC I/O register. */
17253a03eb79SAndrew Vasquez 	WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
17263a03eb79SAndrew Vasquez 	fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
17273a03eb79SAndrew Vasquez 
17283a03eb79SAndrew Vasquez 	/* Mailbox registers. */
17293a03eb79SAndrew Vasquez 	mbx_reg = &reg->mailbox0;
17303a03eb79SAndrew Vasquez 	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
17313a03eb79SAndrew Vasquez 		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
17323a03eb79SAndrew Vasquez 
17333a03eb79SAndrew Vasquez 	/* Transfer sequence registers. */
17343a03eb79SAndrew Vasquez 	iter_reg = fw->xseq_gp_reg;
17353a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
17363a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
17373a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
17383a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
17393a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
17403a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
17413a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
17423a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
17433a03eb79SAndrew Vasquez 
17443a03eb79SAndrew Vasquez 	iter_reg = fw->xseq_0_reg;
17453a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
17463a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
17473a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
17483a03eb79SAndrew Vasquez 
17493a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
17503a03eb79SAndrew Vasquez 
17513a03eb79SAndrew Vasquez 	/* Receive sequence registers. */
17523a03eb79SAndrew Vasquez 	iter_reg = fw->rseq_gp_reg;
17533a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
17543a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
17553a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
17563a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
17573a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
17583a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
17593a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
17603a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
17613a03eb79SAndrew Vasquez 
17623a03eb79SAndrew Vasquez 	iter_reg = fw->rseq_0_reg;
17633a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
17643a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
17653a03eb79SAndrew Vasquez 
17663a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
17673a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
17683a03eb79SAndrew Vasquez 
17693a03eb79SAndrew Vasquez 	/* Auxiliary sequence registers. */
17703a03eb79SAndrew Vasquez 	iter_reg = fw->aseq_gp_reg;
17713a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
17723a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
17733a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
17743a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
17753a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
17763a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
17773a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
17783a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xB070, 16, iter_reg);
17793a03eb79SAndrew Vasquez 
17803a03eb79SAndrew Vasquez 	iter_reg = fw->aseq_0_reg;
17813a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
17823a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
17833a03eb79SAndrew Vasquez 
17843a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
17853a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
17863a03eb79SAndrew Vasquez 
17873a03eb79SAndrew Vasquez 	/* Command DMA registers. */
17883a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
17893a03eb79SAndrew Vasquez 
17903a03eb79SAndrew Vasquez 	/* Queues. */
17913a03eb79SAndrew Vasquez 	iter_reg = fw->req0_dma_reg;
17923a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
17933a03eb79SAndrew Vasquez 	dmp_reg = &reg->iobase_q;
17943a03eb79SAndrew Vasquez 	for (cnt = 0; cnt < 7; cnt++)
17953a03eb79SAndrew Vasquez 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
17963a03eb79SAndrew Vasquez 
17973a03eb79SAndrew Vasquez 	iter_reg = fw->resp0_dma_reg;
17983a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
17993a03eb79SAndrew Vasquez 	dmp_reg = &reg->iobase_q;
18003a03eb79SAndrew Vasquez 	for (cnt = 0; cnt < 7; cnt++)
18013a03eb79SAndrew Vasquez 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
18023a03eb79SAndrew Vasquez 
18033a03eb79SAndrew Vasquez 	iter_reg = fw->req1_dma_reg;
18043a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
18053a03eb79SAndrew Vasquez 	dmp_reg = &reg->iobase_q;
18063a03eb79SAndrew Vasquez 	for (cnt = 0; cnt < 7; cnt++)
18073a03eb79SAndrew Vasquez 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
18083a03eb79SAndrew Vasquez 
18093a03eb79SAndrew Vasquez 	/* Transmit DMA registers. */
18103a03eb79SAndrew Vasquez 	iter_reg = fw->xmt0_dma_reg;
18113a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
18123a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x7610, 16, iter_reg);
18133a03eb79SAndrew Vasquez 
18143a03eb79SAndrew Vasquez 	iter_reg = fw->xmt1_dma_reg;
18153a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
18163a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x7630, 16, iter_reg);
18173a03eb79SAndrew Vasquez 
18183a03eb79SAndrew Vasquez 	iter_reg = fw->xmt2_dma_reg;
18193a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
18203a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x7650, 16, iter_reg);
18213a03eb79SAndrew Vasquez 
18223a03eb79SAndrew Vasquez 	iter_reg = fw->xmt3_dma_reg;
18233a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
18243a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x7670, 16, iter_reg);
18253a03eb79SAndrew Vasquez 
18263a03eb79SAndrew Vasquez 	iter_reg = fw->xmt4_dma_reg;
18273a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
18283a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x7690, 16, iter_reg);
18293a03eb79SAndrew Vasquez 
18303a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
18313a03eb79SAndrew Vasquez 
18323a03eb79SAndrew Vasquez 	/* Receive DMA registers. */
18333a03eb79SAndrew Vasquez 	iter_reg = fw->rcvt0_data_dma_reg;
18343a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
18353a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x7710, 16, iter_reg);
18363a03eb79SAndrew Vasquez 
18373a03eb79SAndrew Vasquez 	iter_reg = fw->rcvt1_data_dma_reg;
18383a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
18393a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x7730, 16, iter_reg);
18403a03eb79SAndrew Vasquez 
18413a03eb79SAndrew Vasquez 	/* RISC registers. */
18423a03eb79SAndrew Vasquez 	iter_reg = fw->risc_gp_reg;
18433a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
18443a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
18453a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
18463a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
18473a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
18483a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
18493a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
18503a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
18513a03eb79SAndrew Vasquez 
18523a03eb79SAndrew Vasquez 	/* Local memory controller registers. */
18533a03eb79SAndrew Vasquez 	iter_reg = fw->lmc_reg;
18543a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
18553a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
18563a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
18573a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
18583a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
18593a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
18603a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
18613a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x3070, 16, iter_reg);
18623a03eb79SAndrew Vasquez 
18633a03eb79SAndrew Vasquez 	/* Fibre Protocol Module registers. */
18643a03eb79SAndrew Vasquez 	iter_reg = fw->fpm_hdw_reg;
18653a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
18663a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
18673a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
18683a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
18693a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
18703a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
18713a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
18723a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
18733a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
18743a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
18753a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
18763a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
18773a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
18783a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
18793a03eb79SAndrew Vasquez 
18803a03eb79SAndrew Vasquez 	/* Frame Buffer registers. */
18813a03eb79SAndrew Vasquez 	iter_reg = fw->fb_hdw_reg;
18823a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
18833a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
18843a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
18853a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
18863a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
18873a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
18883a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
18893a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
18903a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
18913a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
18923a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
18933a03eb79SAndrew Vasquez 	iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
18943a03eb79SAndrew Vasquez 	qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
18953a03eb79SAndrew Vasquez 
18963a03eb79SAndrew Vasquez 	/* Multi queue registers */
18973a03eb79SAndrew Vasquez 	nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
18983a03eb79SAndrew Vasquez 	    &last_chain);
18993a03eb79SAndrew Vasquez 
19003a03eb79SAndrew Vasquez 	rval = qla24xx_soft_reset(ha);
19013a03eb79SAndrew Vasquez 	if (rval != QLA_SUCCESS)
19023a03eb79SAndrew Vasquez 		goto qla81xx_fw_dump_failed_0;
19033a03eb79SAndrew Vasquez 
19043a03eb79SAndrew Vasquez 	rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
19053a03eb79SAndrew Vasquez 	    &nxt);
19063a03eb79SAndrew Vasquez 	if (rval != QLA_SUCCESS)
19073a03eb79SAndrew Vasquez 		goto qla81xx_fw_dump_failed_0;
19083a03eb79SAndrew Vasquez 
19093a03eb79SAndrew Vasquez 	nxt = qla2xxx_copy_queues(ha, nxt);
19103a03eb79SAndrew Vasquez 
19117f544d00SBart Van Assche 	qla24xx_copy_eft(ha, nxt);
19123a03eb79SAndrew Vasquez 
19133a03eb79SAndrew Vasquez 	/* Chain entries -- started with MQ. */
1914050c9bb1SGiridhar Malavali 	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
1915050c9bb1SGiridhar Malavali 	nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
19162d70c103SNicholas Bellinger 	nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
19173a03eb79SAndrew Vasquez 	if (last_chain) {
19183a03eb79SAndrew Vasquez 		ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
19193a03eb79SAndrew Vasquez 		*last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
19203a03eb79SAndrew Vasquez 	}
19213a03eb79SAndrew Vasquez 
1922050c9bb1SGiridhar Malavali 	/* Adjust valid length. */
1923050c9bb1SGiridhar Malavali 	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1924050c9bb1SGiridhar Malavali 
19253a03eb79SAndrew Vasquez qla81xx_fw_dump_failed_0:
19263420d36cSAndrew Vasquez 	qla2xxx_dump_post_process(base_vha, rval);
19273a03eb79SAndrew Vasquez 
19283a03eb79SAndrew Vasquez qla81xx_fw_dump_failed:
19293a03eb79SAndrew Vasquez 	if (!hardware_locked)
19303a03eb79SAndrew Vasquez 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
19313a03eb79SAndrew Vasquez }
19323a03eb79SAndrew Vasquez 
19336246b8a1SGiridhar Malavali void
19346246b8a1SGiridhar Malavali qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
19356246b8a1SGiridhar Malavali {
19366246b8a1SGiridhar Malavali 	int		rval;
19376246b8a1SGiridhar Malavali 	uint32_t	cnt, reg_data;
19386246b8a1SGiridhar Malavali 	uint32_t	risc_address;
19396246b8a1SGiridhar Malavali 	struct qla_hw_data *ha = vha->hw;
19406246b8a1SGiridhar Malavali 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
19416246b8a1SGiridhar Malavali 	uint32_t __iomem *dmp_reg;
19426246b8a1SGiridhar Malavali 	uint32_t	*iter_reg;
19436246b8a1SGiridhar Malavali 	uint16_t __iomem *mbx_reg;
19446246b8a1SGiridhar Malavali 	unsigned long	flags;
19456246b8a1SGiridhar Malavali 	struct qla83xx_fw_dump *fw;
19466246b8a1SGiridhar Malavali 	uint32_t	ext_mem_cnt;
19476246b8a1SGiridhar Malavali 	void		*nxt, *nxt_chain;
19486246b8a1SGiridhar Malavali 	uint32_t	*last_chain = NULL;
19496246b8a1SGiridhar Malavali 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
19506246b8a1SGiridhar Malavali 
19516246b8a1SGiridhar Malavali 	risc_address = ext_mem_cnt = 0;
19526246b8a1SGiridhar Malavali 	flags = 0;
195361f098ddSHiral Patel 	ha->fw_dump_cap_flags = 0;
19546246b8a1SGiridhar Malavali 
19556246b8a1SGiridhar Malavali 	if (!hardware_locked)
19566246b8a1SGiridhar Malavali 		spin_lock_irqsave(&ha->hardware_lock, flags);
19576246b8a1SGiridhar Malavali 
19586246b8a1SGiridhar Malavali 	if (!ha->fw_dump) {
19596246b8a1SGiridhar Malavali 		ql_log(ql_log_warn, vha, 0xd00c,
19606246b8a1SGiridhar Malavali 		    "No buffer available for dump!!!\n");
19616246b8a1SGiridhar Malavali 		goto qla83xx_fw_dump_failed;
19626246b8a1SGiridhar Malavali 	}
19636246b8a1SGiridhar Malavali 
19646246b8a1SGiridhar Malavali 	if (ha->fw_dumped) {
19656246b8a1SGiridhar Malavali 		ql_log(ql_log_warn, vha, 0xd00d,
19666246b8a1SGiridhar Malavali 		    "Firmware has been previously dumped (%p) -- ignoring "
19676246b8a1SGiridhar Malavali 		    "request...\n", ha->fw_dump);
19686246b8a1SGiridhar Malavali 		goto qla83xx_fw_dump_failed;
19696246b8a1SGiridhar Malavali 	}
19706246b8a1SGiridhar Malavali 	fw = &ha->fw_dump->isp.isp83;
19716246b8a1SGiridhar Malavali 	qla2xxx_prep_dump(ha, ha->fw_dump);
19726246b8a1SGiridhar Malavali 
19736246b8a1SGiridhar Malavali 	fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
19746246b8a1SGiridhar Malavali 
19752f389fc4SHiral Patel 	/*
19762f389fc4SHiral Patel 	 * Pause RISC. No need to track timeout, as resetting the chip
19772f389fc4SHiral Patel 	 * is the right approach incase of pause timeout
19782f389fc4SHiral Patel 	 */
197961f098ddSHiral Patel 	qla24xx_pause_risc(reg, ha);
19806246b8a1SGiridhar Malavali 
19816246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_addr, 0x6000);
19826246b8a1SGiridhar Malavali 	dmp_reg = &reg->iobase_window;
19836246b8a1SGiridhar Malavali 	reg_data = RD_REG_DWORD(dmp_reg);
19846246b8a1SGiridhar Malavali 	WRT_REG_DWORD(dmp_reg, 0);
19856246b8a1SGiridhar Malavali 
19866246b8a1SGiridhar Malavali 	dmp_reg = &reg->unused_4_1[0];
19876246b8a1SGiridhar Malavali 	reg_data = RD_REG_DWORD(dmp_reg);
19886246b8a1SGiridhar Malavali 	WRT_REG_DWORD(dmp_reg, 0);
19896246b8a1SGiridhar Malavali 
19906246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_addr, 0x6010);
19916246b8a1SGiridhar Malavali 	dmp_reg = &reg->unused_4_1[2];
19926246b8a1SGiridhar Malavali 	reg_data = RD_REG_DWORD(dmp_reg);
19936246b8a1SGiridhar Malavali 	WRT_REG_DWORD(dmp_reg, 0);
19946246b8a1SGiridhar Malavali 
19956246b8a1SGiridhar Malavali 	/* select PCR and disable ecc checking and correction */
19966246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
19976246b8a1SGiridhar Malavali 	RD_REG_DWORD(&reg->iobase_addr);
19986246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0x60000000);	/* write to F0h = PCR */
19996246b8a1SGiridhar Malavali 
20006246b8a1SGiridhar Malavali 	/* Host/Risc registers. */
20016246b8a1SGiridhar Malavali 	iter_reg = fw->host_risc_reg;
20026246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
20036246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7010, 16, iter_reg);
20046246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x7040, 16, iter_reg);
20056246b8a1SGiridhar Malavali 
20066246b8a1SGiridhar Malavali 	/* PCIe registers. */
20076246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
20086246b8a1SGiridhar Malavali 	RD_REG_DWORD(&reg->iobase_addr);
20096246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_window, 0x01);
20106246b8a1SGiridhar Malavali 	dmp_reg = &reg->iobase_c4;
20116246b8a1SGiridhar Malavali 	fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++));
20126246b8a1SGiridhar Malavali 	fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
20136246b8a1SGiridhar Malavali 	fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
20146246b8a1SGiridhar Malavali 	fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
20156246b8a1SGiridhar Malavali 
20166246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_window, 0x00);
20176246b8a1SGiridhar Malavali 	RD_REG_DWORD(&reg->iobase_window);
20186246b8a1SGiridhar Malavali 
20196246b8a1SGiridhar Malavali 	/* Host interface registers. */
20206246b8a1SGiridhar Malavali 	dmp_reg = &reg->flash_addr;
20216246b8a1SGiridhar Malavali 	for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
20226246b8a1SGiridhar Malavali 		fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
20236246b8a1SGiridhar Malavali 
20246246b8a1SGiridhar Malavali 	/* Disable interrupts. */
20256246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->ictrl, 0);
20266246b8a1SGiridhar Malavali 	RD_REG_DWORD(&reg->ictrl);
20276246b8a1SGiridhar Malavali 
20286246b8a1SGiridhar Malavali 	/* Shadow registers. */
20296246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
20306246b8a1SGiridhar Malavali 	RD_REG_DWORD(&reg->iobase_addr);
20316246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
20326246b8a1SGiridhar Malavali 	fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20336246b8a1SGiridhar Malavali 
20346246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
20356246b8a1SGiridhar Malavali 	fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20366246b8a1SGiridhar Malavali 
20376246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
20386246b8a1SGiridhar Malavali 	fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20396246b8a1SGiridhar Malavali 
20406246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
20416246b8a1SGiridhar Malavali 	fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20426246b8a1SGiridhar Malavali 
20436246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
20446246b8a1SGiridhar Malavali 	fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20456246b8a1SGiridhar Malavali 
20466246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
20476246b8a1SGiridhar Malavali 	fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20486246b8a1SGiridhar Malavali 
20496246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
20506246b8a1SGiridhar Malavali 	fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20516246b8a1SGiridhar Malavali 
20526246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
20536246b8a1SGiridhar Malavali 	fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20546246b8a1SGiridhar Malavali 
20556246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
20566246b8a1SGiridhar Malavali 	fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20576246b8a1SGiridhar Malavali 
20586246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
20596246b8a1SGiridhar Malavali 	fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20606246b8a1SGiridhar Malavali 
20616246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
20626246b8a1SGiridhar Malavali 	fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
20636246b8a1SGiridhar Malavali 
20646246b8a1SGiridhar Malavali 	/* RISC I/O register. */
20656246b8a1SGiridhar Malavali 	WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
20666246b8a1SGiridhar Malavali 	fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
20676246b8a1SGiridhar Malavali 
20686246b8a1SGiridhar Malavali 	/* Mailbox registers. */
20696246b8a1SGiridhar Malavali 	mbx_reg = &reg->mailbox0;
20706246b8a1SGiridhar Malavali 	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
20716246b8a1SGiridhar Malavali 		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
20726246b8a1SGiridhar Malavali 
20736246b8a1SGiridhar Malavali 	/* Transfer sequence registers. */
20746246b8a1SGiridhar Malavali 	iter_reg = fw->xseq_gp_reg;
20756246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBE00, 16, iter_reg);
20766246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBE10, 16, iter_reg);
20776246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBE20, 16, iter_reg);
20786246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBE30, 16, iter_reg);
20796246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBE40, 16, iter_reg);
20806246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBE50, 16, iter_reg);
20816246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBE60, 16, iter_reg);
20826246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBE70, 16, iter_reg);
20836246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
20846246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
20856246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
20866246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
20876246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
20886246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
20896246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
20906246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
20916246b8a1SGiridhar Malavali 
20926246b8a1SGiridhar Malavali 	iter_reg = fw->xseq_0_reg;
20936246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
20946246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
20956246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
20966246b8a1SGiridhar Malavali 
20976246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
20986246b8a1SGiridhar Malavali 
20996246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xBEF0, 16, fw->xseq_2_reg);
21006246b8a1SGiridhar Malavali 
21016246b8a1SGiridhar Malavali 	/* Receive sequence registers. */
21026246b8a1SGiridhar Malavali 	iter_reg = fw->rseq_gp_reg;
21036246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFE00, 16, iter_reg);
21046246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFE10, 16, iter_reg);
21056246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFE20, 16, iter_reg);
21066246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFE30, 16, iter_reg);
21076246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFE40, 16, iter_reg);
21086246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFE50, 16, iter_reg);
21096246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFE60, 16, iter_reg);
21106246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFE70, 16, iter_reg);
21116246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
21126246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
21136246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
21146246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
21156246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
21166246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
21176246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
21186246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
21196246b8a1SGiridhar Malavali 
21206246b8a1SGiridhar Malavali 	iter_reg = fw->rseq_0_reg;
21216246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
21226246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
21236246b8a1SGiridhar Malavali 
21246246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
21256246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
21266246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xFEF0, 16, fw->rseq_3_reg);
21276246b8a1SGiridhar Malavali 
21286246b8a1SGiridhar Malavali 	/* Auxiliary sequence registers. */
21296246b8a1SGiridhar Malavali 	iter_reg = fw->aseq_gp_reg;
21306246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
21316246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
21326246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
21336246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
21346246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
21356246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
21366246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
21376246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB070, 16, iter_reg);
21386246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB100, 16, iter_reg);
21396246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB110, 16, iter_reg);
21406246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB120, 16, iter_reg);
21416246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB130, 16, iter_reg);
21426246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB140, 16, iter_reg);
21436246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB150, 16, iter_reg);
21446246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB160, 16, iter_reg);
21456246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xB170, 16, iter_reg);
21466246b8a1SGiridhar Malavali 
21476246b8a1SGiridhar Malavali 	iter_reg = fw->aseq_0_reg;
21486246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
21496246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
21506246b8a1SGiridhar Malavali 
21516246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
21526246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
21536246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0xB1F0, 16, fw->aseq_3_reg);
21546246b8a1SGiridhar Malavali 
21556246b8a1SGiridhar Malavali 	/* Command DMA registers. */
21566246b8a1SGiridhar Malavali 	iter_reg = fw->cmd_dma_reg;
21576246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7100, 16, iter_reg);
21586246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7120, 16, iter_reg);
21596246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7130, 16, iter_reg);
21606246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x71F0, 16, iter_reg);
21616246b8a1SGiridhar Malavali 
21626246b8a1SGiridhar Malavali 	/* Queues. */
21636246b8a1SGiridhar Malavali 	iter_reg = fw->req0_dma_reg;
21646246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
21656246b8a1SGiridhar Malavali 	dmp_reg = &reg->iobase_q;
21666246b8a1SGiridhar Malavali 	for (cnt = 0; cnt < 7; cnt++)
21676246b8a1SGiridhar Malavali 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
21686246b8a1SGiridhar Malavali 
21696246b8a1SGiridhar Malavali 	iter_reg = fw->resp0_dma_reg;
21706246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
21716246b8a1SGiridhar Malavali 	dmp_reg = &reg->iobase_q;
21726246b8a1SGiridhar Malavali 	for (cnt = 0; cnt < 7; cnt++)
21736246b8a1SGiridhar Malavali 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
21746246b8a1SGiridhar Malavali 
21756246b8a1SGiridhar Malavali 	iter_reg = fw->req1_dma_reg;
21766246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
21776246b8a1SGiridhar Malavali 	dmp_reg = &reg->iobase_q;
21786246b8a1SGiridhar Malavali 	for (cnt = 0; cnt < 7; cnt++)
21796246b8a1SGiridhar Malavali 		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
21806246b8a1SGiridhar Malavali 
21816246b8a1SGiridhar Malavali 	/* Transmit DMA registers. */
21826246b8a1SGiridhar Malavali 	iter_reg = fw->xmt0_dma_reg;
21836246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
21846246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x7610, 16, iter_reg);
21856246b8a1SGiridhar Malavali 
21866246b8a1SGiridhar Malavali 	iter_reg = fw->xmt1_dma_reg;
21876246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
21886246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x7630, 16, iter_reg);
21896246b8a1SGiridhar Malavali 
21906246b8a1SGiridhar Malavali 	iter_reg = fw->xmt2_dma_reg;
21916246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
21926246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x7650, 16, iter_reg);
21936246b8a1SGiridhar Malavali 
21946246b8a1SGiridhar Malavali 	iter_reg = fw->xmt3_dma_reg;
21956246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
21966246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x7670, 16, iter_reg);
21976246b8a1SGiridhar Malavali 
21986246b8a1SGiridhar Malavali 	iter_reg = fw->xmt4_dma_reg;
21996246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
22006246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x7690, 16, iter_reg);
22016246b8a1SGiridhar Malavali 
22026246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
22036246b8a1SGiridhar Malavali 
22046246b8a1SGiridhar Malavali 	/* Receive DMA registers. */
22056246b8a1SGiridhar Malavali 	iter_reg = fw->rcvt0_data_dma_reg;
22066246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
22076246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x7710, 16, iter_reg);
22086246b8a1SGiridhar Malavali 
22096246b8a1SGiridhar Malavali 	iter_reg = fw->rcvt1_data_dma_reg;
22106246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
22116246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x7730, 16, iter_reg);
22126246b8a1SGiridhar Malavali 
22136246b8a1SGiridhar Malavali 	/* RISC registers. */
22146246b8a1SGiridhar Malavali 	iter_reg = fw->risc_gp_reg;
22156246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
22166246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
22176246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
22186246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
22196246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
22206246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
22216246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
22226246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
22236246b8a1SGiridhar Malavali 
22246246b8a1SGiridhar Malavali 	/* Local memory controller registers. */
22256246b8a1SGiridhar Malavali 	iter_reg = fw->lmc_reg;
22266246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
22276246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
22286246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
22296246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
22306246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
22316246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
22326246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
22336246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x3070, 16, iter_reg);
22346246b8a1SGiridhar Malavali 
22356246b8a1SGiridhar Malavali 	/* Fibre Protocol Module registers. */
22366246b8a1SGiridhar Malavali 	iter_reg = fw->fpm_hdw_reg;
22376246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
22386246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
22396246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
22406246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
22416246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
22426246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
22436246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
22446246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
22456246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
22466246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
22476246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
22486246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
22496246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
22506246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
22516246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x40E0, 16, iter_reg);
22526246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x40F0, 16, iter_reg);
22536246b8a1SGiridhar Malavali 
22546246b8a1SGiridhar Malavali 	/* RQ0 Array registers. */
22556246b8a1SGiridhar Malavali 	iter_reg = fw->rq0_array_reg;
22566246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5C00, 16, iter_reg);
22576246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5C10, 16, iter_reg);
22586246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5C20, 16, iter_reg);
22596246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5C30, 16, iter_reg);
22606246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5C40, 16, iter_reg);
22616246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5C50, 16, iter_reg);
22626246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5C60, 16, iter_reg);
22636246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5C70, 16, iter_reg);
22646246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5C80, 16, iter_reg);
22656246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5C90, 16, iter_reg);
22666246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5CA0, 16, iter_reg);
22676246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5CB0, 16, iter_reg);
22686246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5CC0, 16, iter_reg);
22696246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5CD0, 16, iter_reg);
22706246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5CE0, 16, iter_reg);
22716246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x5CF0, 16, iter_reg);
22726246b8a1SGiridhar Malavali 
22736246b8a1SGiridhar Malavali 	/* RQ1 Array registers. */
22746246b8a1SGiridhar Malavali 	iter_reg = fw->rq1_array_reg;
22756246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5D00, 16, iter_reg);
22766246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5D10, 16, iter_reg);
22776246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5D20, 16, iter_reg);
22786246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5D30, 16, iter_reg);
22796246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5D40, 16, iter_reg);
22806246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5D50, 16, iter_reg);
22816246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5D60, 16, iter_reg);
22826246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5D70, 16, iter_reg);
22836246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5D80, 16, iter_reg);
22846246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5D90, 16, iter_reg);
22856246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5DA0, 16, iter_reg);
22866246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5DB0, 16, iter_reg);
22876246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5DC0, 16, iter_reg);
22886246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5DD0, 16, iter_reg);
22896246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5DE0, 16, iter_reg);
22906246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x5DF0, 16, iter_reg);
22916246b8a1SGiridhar Malavali 
22926246b8a1SGiridhar Malavali 	/* RP0 Array registers. */
22936246b8a1SGiridhar Malavali 	iter_reg = fw->rp0_array_reg;
22946246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5E00, 16, iter_reg);
22956246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5E10, 16, iter_reg);
22966246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5E20, 16, iter_reg);
22976246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5E30, 16, iter_reg);
22986246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5E40, 16, iter_reg);
22996246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5E50, 16, iter_reg);
23006246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5E60, 16, iter_reg);
23016246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5E70, 16, iter_reg);
23026246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5E80, 16, iter_reg);
23036246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5E90, 16, iter_reg);
23046246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5EA0, 16, iter_reg);
23056246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5EB0, 16, iter_reg);
23066246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5EC0, 16, iter_reg);
23076246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5ED0, 16, iter_reg);
23086246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5EE0, 16, iter_reg);
23096246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x5EF0, 16, iter_reg);
23106246b8a1SGiridhar Malavali 
23116246b8a1SGiridhar Malavali 	/* RP1 Array registers. */
23126246b8a1SGiridhar Malavali 	iter_reg = fw->rp1_array_reg;
23136246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5F00, 16, iter_reg);
23146246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5F10, 16, iter_reg);
23156246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5F20, 16, iter_reg);
23166246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5F30, 16, iter_reg);
23176246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5F40, 16, iter_reg);
23186246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5F50, 16, iter_reg);
23196246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5F60, 16, iter_reg);
23206246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5F70, 16, iter_reg);
23216246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5F80, 16, iter_reg);
23226246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5F90, 16, iter_reg);
23236246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5FA0, 16, iter_reg);
23246246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5FB0, 16, iter_reg);
23256246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5FC0, 16, iter_reg);
23266246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5FD0, 16, iter_reg);
23276246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x5FE0, 16, iter_reg);
23286246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x5FF0, 16, iter_reg);
23296246b8a1SGiridhar Malavali 
23306246b8a1SGiridhar Malavali 	iter_reg = fw->at0_array_reg;
23316246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7080, 16, iter_reg);
23326246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x7090, 16, iter_reg);
23336246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x70A0, 16, iter_reg);
23346246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x70B0, 16, iter_reg);
23356246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x70C0, 16, iter_reg);
23366246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x70D0, 16, iter_reg);
23376246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x70E0, 16, iter_reg);
23386246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x70F0, 16, iter_reg);
23396246b8a1SGiridhar Malavali 
23406246b8a1SGiridhar Malavali 	/* I/O Queue Control registers. */
23416246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x7800, 16, fw->queue_control_reg);
23426246b8a1SGiridhar Malavali 
23436246b8a1SGiridhar Malavali 	/* Frame Buffer registers. */
23446246b8a1SGiridhar Malavali 	iter_reg = fw->fb_hdw_reg;
23456246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
23466246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
23476246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
23486246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
23496246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
23506246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6060, 16, iter_reg);
23516246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6070, 16, iter_reg);
23526246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
23536246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
23546246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
23556246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
23566246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
23576246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
23586246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
23596246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6530, 16, iter_reg);
23606246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6540, 16, iter_reg);
23616246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6550, 16, iter_reg);
23626246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6560, 16, iter_reg);
23636246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6570, 16, iter_reg);
23646246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6580, 16, iter_reg);
23656246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x6590, 16, iter_reg);
23666246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x65A0, 16, iter_reg);
23676246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x65B0, 16, iter_reg);
23686246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x65C0, 16, iter_reg);
23696246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x65D0, 16, iter_reg);
23706246b8a1SGiridhar Malavali 	iter_reg = qla24xx_read_window(reg, 0x65E0, 16, iter_reg);
23716246b8a1SGiridhar Malavali 	qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
23726246b8a1SGiridhar Malavali 
23736246b8a1SGiridhar Malavali 	/* Multi queue registers */
23746246b8a1SGiridhar Malavali 	nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
23756246b8a1SGiridhar Malavali 	    &last_chain);
23766246b8a1SGiridhar Malavali 
23776246b8a1SGiridhar Malavali 	rval = qla24xx_soft_reset(ha);
23786246b8a1SGiridhar Malavali 	if (rval != QLA_SUCCESS) {
23796246b8a1SGiridhar Malavali 		ql_log(ql_log_warn, vha, 0xd00e,
23806246b8a1SGiridhar Malavali 		    "SOFT RESET FAILED, forcing continuation of dump!!!\n");
23816246b8a1SGiridhar Malavali 		rval = QLA_SUCCESS;
23826246b8a1SGiridhar Malavali 
23836246b8a1SGiridhar Malavali 		ql_log(ql_log_warn, vha, 0xd00f, "try a bigger hammer!!!\n");
23846246b8a1SGiridhar Malavali 
23856246b8a1SGiridhar Malavali 		WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
23866246b8a1SGiridhar Malavali 		RD_REG_DWORD(&reg->hccr);
23876246b8a1SGiridhar Malavali 
23886246b8a1SGiridhar Malavali 		WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
23896246b8a1SGiridhar Malavali 		RD_REG_DWORD(&reg->hccr);
23906246b8a1SGiridhar Malavali 
23916246b8a1SGiridhar Malavali 		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
23926246b8a1SGiridhar Malavali 		RD_REG_DWORD(&reg->hccr);
23936246b8a1SGiridhar Malavali 
23946246b8a1SGiridhar Malavali 		for (cnt = 30000; cnt && (RD_REG_WORD(&reg->mailbox0)); cnt--)
23956246b8a1SGiridhar Malavali 			udelay(5);
23966246b8a1SGiridhar Malavali 
23976246b8a1SGiridhar Malavali 		if (!cnt) {
23986246b8a1SGiridhar Malavali 			nxt = fw->code_ram;
23998c0bc701SSaurav Kashyap 			nxt += sizeof(fw->code_ram);
24006246b8a1SGiridhar Malavali 			nxt += (ha->fw_memory_size - 0x100000 + 1);
24016246b8a1SGiridhar Malavali 			goto copy_queue;
240261f098ddSHiral Patel 		} else {
240361f098ddSHiral Patel 			set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
24046246b8a1SGiridhar Malavali 			ql_log(ql_log_warn, vha, 0xd010,
24056246b8a1SGiridhar Malavali 			    "bigger hammer success?\n");
24066246b8a1SGiridhar Malavali 		}
240761f098ddSHiral Patel 	}
24086246b8a1SGiridhar Malavali 
24096246b8a1SGiridhar Malavali 	rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
24106246b8a1SGiridhar Malavali 	    &nxt);
24116246b8a1SGiridhar Malavali 	if (rval != QLA_SUCCESS)
24126246b8a1SGiridhar Malavali 		goto qla83xx_fw_dump_failed_0;
24136246b8a1SGiridhar Malavali 
24146246b8a1SGiridhar Malavali copy_queue:
24156246b8a1SGiridhar Malavali 	nxt = qla2xxx_copy_queues(ha, nxt);
24166246b8a1SGiridhar Malavali 
24177f544d00SBart Van Assche 	qla24xx_copy_eft(ha, nxt);
24186246b8a1SGiridhar Malavali 
24196246b8a1SGiridhar Malavali 	/* Chain entries -- started with MQ. */
24206246b8a1SGiridhar Malavali 	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
24216246b8a1SGiridhar Malavali 	nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
24222d70c103SNicholas Bellinger 	nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
24236246b8a1SGiridhar Malavali 	if (last_chain) {
24246246b8a1SGiridhar Malavali 		ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
24256246b8a1SGiridhar Malavali 		*last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
24266246b8a1SGiridhar Malavali 	}
24276246b8a1SGiridhar Malavali 
24286246b8a1SGiridhar Malavali 	/* Adjust valid length. */
24296246b8a1SGiridhar Malavali 	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
24306246b8a1SGiridhar Malavali 
24316246b8a1SGiridhar Malavali qla83xx_fw_dump_failed_0:
24326246b8a1SGiridhar Malavali 	qla2xxx_dump_post_process(base_vha, rval);
24336246b8a1SGiridhar Malavali 
24346246b8a1SGiridhar Malavali qla83xx_fw_dump_failed:
24356246b8a1SGiridhar Malavali 	if (!hardware_locked)
24366246b8a1SGiridhar Malavali 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
24376246b8a1SGiridhar Malavali }
24386246b8a1SGiridhar Malavali 
24391da177e4SLinus Torvalds /****************************************************************************/
24401da177e4SLinus Torvalds /*                         Driver Debug Functions.                          */
24411da177e4SLinus Torvalds /****************************************************************************/
2442cfb0919cSChad Dupuis 
2443cfb0919cSChad Dupuis static inline int
2444cfb0919cSChad Dupuis ql_mask_match(uint32_t level)
2445cfb0919cSChad Dupuis {
2446cfb0919cSChad Dupuis 	if (ql2xextended_error_logging == 1)
2447cfb0919cSChad Dupuis 		ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK;
2448cfb0919cSChad Dupuis 	return (level & ql2xextended_error_logging) == level;
2449cfb0919cSChad Dupuis }
2450cfb0919cSChad Dupuis 
24513ce8866cSSaurav Kashyap /*
24523ce8866cSSaurav Kashyap  * This function is for formatting and logging debug information.
24533ce8866cSSaurav Kashyap  * It is to be used when vha is available. It formats the message
24543ce8866cSSaurav Kashyap  * and logs it to the messages file.
24553ce8866cSSaurav Kashyap  * parameters:
24563ce8866cSSaurav Kashyap  * level: The level of the debug messages to be printed.
24573ce8866cSSaurav Kashyap  *        If ql2xextended_error_logging value is correctly set,
24583ce8866cSSaurav Kashyap  *        this message will appear in the messages file.
24593ce8866cSSaurav Kashyap  * vha:   Pointer to the scsi_qla_host_t.
24603ce8866cSSaurav Kashyap  * id:    This is a unique identifier for the level. It identifies the
24613ce8866cSSaurav Kashyap  *        part of the code from where the message originated.
24623ce8866cSSaurav Kashyap  * msg:   The message to be displayed.
24633ce8866cSSaurav Kashyap  */
24643ce8866cSSaurav Kashyap void
2465086b3e8aSJoe Perches ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...)
2466086b3e8aSJoe Perches {
2467086b3e8aSJoe Perches 	va_list va;
2468086b3e8aSJoe Perches 	struct va_format vaf;
24693ce8866cSSaurav Kashyap 
2470cfb0919cSChad Dupuis 	if (!ql_mask_match(level))
2471086b3e8aSJoe Perches 		return;
24723ce8866cSSaurav Kashyap 
2473086b3e8aSJoe Perches 	va_start(va, fmt);
24743ce8866cSSaurav Kashyap 
2475086b3e8aSJoe Perches 	vaf.fmt = fmt;
2476086b3e8aSJoe Perches 	vaf.va = &va;
24773ce8866cSSaurav Kashyap 
24783ce8866cSSaurav Kashyap 	if (vha != NULL) {
2479086b3e8aSJoe Perches 		const struct pci_dev *pdev = vha->hw->pdev;
24803ce8866cSSaurav Kashyap 		/* <module-name> <pci-name> <msg-id>:<host> Message */
2481086b3e8aSJoe Perches 		pr_warn("%s [%s]-%04x:%ld: %pV",
2482086b3e8aSJoe Perches 			QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset,
2483086b3e8aSJoe Perches 			vha->host_no, &vaf);
2484086b3e8aSJoe Perches 	} else {
2485086b3e8aSJoe Perches 		pr_warn("%s [%s]-%04x: : %pV",
2486086b3e8aSJoe Perches 			QL_MSGHDR, "0000:00:00.0", id + ql_dbg_offset, &vaf);
24873ce8866cSSaurav Kashyap 	}
24883ce8866cSSaurav Kashyap 
2489086b3e8aSJoe Perches 	va_end(va);
24903ce8866cSSaurav Kashyap 
24913ce8866cSSaurav Kashyap }
24923ce8866cSSaurav Kashyap 
24933ce8866cSSaurav Kashyap /*
24943ce8866cSSaurav Kashyap  * This function is for formatting and logging debug information.
2495d6a03581SMasanari Iida  * It is to be used when vha is not available and pci is available,
24963ce8866cSSaurav Kashyap  * i.e., before host allocation. It formats the message and logs it
24973ce8866cSSaurav Kashyap  * to the messages file.
24983ce8866cSSaurav Kashyap  * parameters:
24993ce8866cSSaurav Kashyap  * level: The level of the debug messages to be printed.
25003ce8866cSSaurav Kashyap  *        If ql2xextended_error_logging value is correctly set,
25013ce8866cSSaurav Kashyap  *        this message will appear in the messages file.
25023ce8866cSSaurav Kashyap  * pdev:  Pointer to the struct pci_dev.
25033ce8866cSSaurav Kashyap  * id:    This is a unique id for the level. It identifies the part
25043ce8866cSSaurav Kashyap  *        of the code from where the message originated.
25053ce8866cSSaurav Kashyap  * msg:   The message to be displayed.
25063ce8866cSSaurav Kashyap  */
25073ce8866cSSaurav Kashyap void
2508086b3e8aSJoe Perches ql_dbg_pci(uint32_t level, struct pci_dev *pdev, int32_t id,
2509086b3e8aSJoe Perches 	   const char *fmt, ...)
2510086b3e8aSJoe Perches {
2511086b3e8aSJoe Perches 	va_list va;
2512086b3e8aSJoe Perches 	struct va_format vaf;
25133ce8866cSSaurav Kashyap 
25143ce8866cSSaurav Kashyap 	if (pdev == NULL)
25153ce8866cSSaurav Kashyap 		return;
2516cfb0919cSChad Dupuis 	if (!ql_mask_match(level))
2517086b3e8aSJoe Perches 		return;
25183ce8866cSSaurav Kashyap 
2519086b3e8aSJoe Perches 	va_start(va, fmt);
25203ce8866cSSaurav Kashyap 
2521086b3e8aSJoe Perches 	vaf.fmt = fmt;
2522086b3e8aSJoe Perches 	vaf.va = &va;
25233ce8866cSSaurav Kashyap 
25243ce8866cSSaurav Kashyap 	/* <module-name> <dev-name>:<msg-id> Message */
2525086b3e8aSJoe Perches 	pr_warn("%s [%s]-%04x: : %pV",
2526086b3e8aSJoe Perches 		QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset, &vaf);
25273ce8866cSSaurav Kashyap 
2528086b3e8aSJoe Perches 	va_end(va);
25293ce8866cSSaurav Kashyap }
25303ce8866cSSaurav Kashyap 
25313ce8866cSSaurav Kashyap /*
25323ce8866cSSaurav Kashyap  * This function is for formatting and logging log messages.
25333ce8866cSSaurav Kashyap  * It is to be used when vha is available. It formats the message
25343ce8866cSSaurav Kashyap  * and logs it to the messages file. All the messages will be logged
25353ce8866cSSaurav Kashyap  * irrespective of value of ql2xextended_error_logging.
25363ce8866cSSaurav Kashyap  * parameters:
25373ce8866cSSaurav Kashyap  * level: The level of the log messages to be printed in the
25383ce8866cSSaurav Kashyap  *        messages file.
25393ce8866cSSaurav Kashyap  * vha:   Pointer to the scsi_qla_host_t
25403ce8866cSSaurav Kashyap  * id:    This is a unique id for the level. It identifies the
25413ce8866cSSaurav Kashyap  *        part of the code from where the message originated.
25423ce8866cSSaurav Kashyap  * msg:   The message to be displayed.
25433ce8866cSSaurav Kashyap  */
25443ce8866cSSaurav Kashyap void
2545086b3e8aSJoe Perches ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...)
2546086b3e8aSJoe Perches {
2547086b3e8aSJoe Perches 	va_list va;
2548086b3e8aSJoe Perches 	struct va_format vaf;
2549086b3e8aSJoe Perches 	char pbuf[128];
25503ce8866cSSaurav Kashyap 
2551086b3e8aSJoe Perches 	if (level > ql_errlev)
2552086b3e8aSJoe Perches 		return;
25533ce8866cSSaurav Kashyap 
25543ce8866cSSaurav Kashyap 	if (vha != NULL) {
2555086b3e8aSJoe Perches 		const struct pci_dev *pdev = vha->hw->pdev;
25563ce8866cSSaurav Kashyap 		/* <module-name> <msg-id>:<host> Message */
2557086b3e8aSJoe Perches 		snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x:%ld: ",
2558086b3e8aSJoe Perches 			QL_MSGHDR, dev_name(&(pdev->dev)), id, vha->host_no);
2559086b3e8aSJoe Perches 	} else {
2560086b3e8aSJoe Perches 		snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
2561086b3e8aSJoe Perches 			QL_MSGHDR, "0000:00:00.0", id);
2562086b3e8aSJoe Perches 	}
2563086b3e8aSJoe Perches 	pbuf[sizeof(pbuf) - 1] = 0;
25643ce8866cSSaurav Kashyap 
2565086b3e8aSJoe Perches 	va_start(va, fmt);
2566086b3e8aSJoe Perches 
2567086b3e8aSJoe Perches 	vaf.fmt = fmt;
2568086b3e8aSJoe Perches 	vaf.va = &va;
25693ce8866cSSaurav Kashyap 
25703ce8866cSSaurav Kashyap 	switch (level) {
257170a3fc76SChad Dupuis 	case ql_log_fatal: /* FATAL LOG */
2572086b3e8aSJoe Perches 		pr_crit("%s%pV", pbuf, &vaf);
25733ce8866cSSaurav Kashyap 		break;
257470a3fc76SChad Dupuis 	case ql_log_warn:
2575086b3e8aSJoe Perches 		pr_err("%s%pV", pbuf, &vaf);
25763ce8866cSSaurav Kashyap 		break;
257770a3fc76SChad Dupuis 	case ql_log_info:
2578086b3e8aSJoe Perches 		pr_warn("%s%pV", pbuf, &vaf);
25793ce8866cSSaurav Kashyap 		break;
25803ce8866cSSaurav Kashyap 	default:
2581086b3e8aSJoe Perches 		pr_info("%s%pV", pbuf, &vaf);
25823ce8866cSSaurav Kashyap 		break;
25833ce8866cSSaurav Kashyap 	}
25843ce8866cSSaurav Kashyap 
2585086b3e8aSJoe Perches 	va_end(va);
25863ce8866cSSaurav Kashyap }
25873ce8866cSSaurav Kashyap 
25883ce8866cSSaurav Kashyap /*
25893ce8866cSSaurav Kashyap  * This function is for formatting and logging log messages.
2590d6a03581SMasanari Iida  * It is to be used when vha is not available and pci is available,
25913ce8866cSSaurav Kashyap  * i.e., before host allocation. It formats the message and logs
25923ce8866cSSaurav Kashyap  * it to the messages file. All the messages are logged irrespective
25933ce8866cSSaurav Kashyap  * of the value of ql2xextended_error_logging.
25943ce8866cSSaurav Kashyap  * parameters:
25953ce8866cSSaurav Kashyap  * level: The level of the log messages to be printed in the
25963ce8866cSSaurav Kashyap  *        messages file.
25973ce8866cSSaurav Kashyap  * pdev:  Pointer to the struct pci_dev.
25983ce8866cSSaurav Kashyap  * id:    This is a unique id for the level. It identifies the
25993ce8866cSSaurav Kashyap  *        part of the code from where the message originated.
26003ce8866cSSaurav Kashyap  * msg:   The message to be displayed.
26013ce8866cSSaurav Kashyap  */
26023ce8866cSSaurav Kashyap void
2603086b3e8aSJoe Perches ql_log_pci(uint32_t level, struct pci_dev *pdev, int32_t id,
2604086b3e8aSJoe Perches 	   const char *fmt, ...)
2605086b3e8aSJoe Perches {
2606086b3e8aSJoe Perches 	va_list va;
2607086b3e8aSJoe Perches 	struct va_format vaf;
2608086b3e8aSJoe Perches 	char pbuf[128];
26093ce8866cSSaurav Kashyap 
26103ce8866cSSaurav Kashyap 	if (pdev == NULL)
26113ce8866cSSaurav Kashyap 		return;
2612086b3e8aSJoe Perches 	if (level > ql_errlev)
2613086b3e8aSJoe Perches 		return;
26143ce8866cSSaurav Kashyap 
26153ce8866cSSaurav Kashyap 	/* <module-name> <dev-name>:<msg-id> Message */
2616086b3e8aSJoe Perches 	snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
2617086b3e8aSJoe Perches 		 QL_MSGHDR, dev_name(&(pdev->dev)), id);
2618086b3e8aSJoe Perches 	pbuf[sizeof(pbuf) - 1] = 0;
26193ce8866cSSaurav Kashyap 
2620086b3e8aSJoe Perches 	va_start(va, fmt);
2621086b3e8aSJoe Perches 
2622086b3e8aSJoe Perches 	vaf.fmt = fmt;
2623086b3e8aSJoe Perches 	vaf.va = &va;
2624086b3e8aSJoe Perches 
26253ce8866cSSaurav Kashyap 	switch (level) {
262670a3fc76SChad Dupuis 	case ql_log_fatal: /* FATAL LOG */
2627086b3e8aSJoe Perches 		pr_crit("%s%pV", pbuf, &vaf);
26283ce8866cSSaurav Kashyap 		break;
262970a3fc76SChad Dupuis 	case ql_log_warn:
2630086b3e8aSJoe Perches 		pr_err("%s%pV", pbuf, &vaf);
26313ce8866cSSaurav Kashyap 		break;
263270a3fc76SChad Dupuis 	case ql_log_info:
2633086b3e8aSJoe Perches 		pr_warn("%s%pV", pbuf, &vaf);
26343ce8866cSSaurav Kashyap 		break;
26353ce8866cSSaurav Kashyap 	default:
2636086b3e8aSJoe Perches 		pr_info("%s%pV", pbuf, &vaf);
26373ce8866cSSaurav Kashyap 		break;
26383ce8866cSSaurav Kashyap 	}
26393ce8866cSSaurav Kashyap 
2640086b3e8aSJoe Perches 	va_end(va);
26413ce8866cSSaurav Kashyap }
26423ce8866cSSaurav Kashyap 
26433ce8866cSSaurav Kashyap void
26443ce8866cSSaurav Kashyap ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id)
26453ce8866cSSaurav Kashyap {
26463ce8866cSSaurav Kashyap 	int i;
26473ce8866cSSaurav Kashyap 	struct qla_hw_data *ha = vha->hw;
26483ce8866cSSaurav Kashyap 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
26493ce8866cSSaurav Kashyap 	struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
26503ce8866cSSaurav Kashyap 	struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
26513ce8866cSSaurav Kashyap 	uint16_t __iomem *mbx_reg;
26523ce8866cSSaurav Kashyap 
2653cfb0919cSChad Dupuis 	if (!ql_mask_match(level))
2654cfb0919cSChad Dupuis 		return;
26553ce8866cSSaurav Kashyap 
26567ec0effdSAtul Deshmukh 	if (IS_P3P_TYPE(ha))
26573ce8866cSSaurav Kashyap 		mbx_reg = &reg82->mailbox_in[0];
26583ce8866cSSaurav Kashyap 	else if (IS_FWI2_CAPABLE(ha))
26593ce8866cSSaurav Kashyap 		mbx_reg = &reg24->mailbox0;
26603ce8866cSSaurav Kashyap 	else
26613ce8866cSSaurav Kashyap 		mbx_reg = MAILBOX_REG(ha, reg, 0);
26623ce8866cSSaurav Kashyap 
26633ce8866cSSaurav Kashyap 	ql_dbg(level, vha, id, "Mailbox registers:\n");
26643ce8866cSSaurav Kashyap 	for (i = 0; i < 6; i++)
26653ce8866cSSaurav Kashyap 		ql_dbg(level, vha, id,
26663ce8866cSSaurav Kashyap 		    "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg++));
26673ce8866cSSaurav Kashyap }
26683ce8866cSSaurav Kashyap 
26693ce8866cSSaurav Kashyap 
26703ce8866cSSaurav Kashyap void
26713ce8866cSSaurav Kashyap ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, int32_t id,
26723ce8866cSSaurav Kashyap 	uint8_t *b, uint32_t size)
26733ce8866cSSaurav Kashyap {
26743ce8866cSSaurav Kashyap 	uint32_t cnt;
26753ce8866cSSaurav Kashyap 	uint8_t c;
2676cfb0919cSChad Dupuis 
2677cfb0919cSChad Dupuis 	if (!ql_mask_match(level))
2678cfb0919cSChad Dupuis 		return;
26793ce8866cSSaurav Kashyap 
26803ce8866cSSaurav Kashyap 	ql_dbg(level, vha, id, " 0   1   2   3   4   5   6   7   8   "
26813ce8866cSSaurav Kashyap 	    "9  Ah  Bh  Ch  Dh  Eh  Fh\n");
26823ce8866cSSaurav Kashyap 	ql_dbg(level, vha, id, "----------------------------------"
26833ce8866cSSaurav Kashyap 	    "----------------------------\n");
26843ce8866cSSaurav Kashyap 
26853ce8866cSSaurav Kashyap 	ql_dbg(level, vha, id, " ");
26863ce8866cSSaurav Kashyap 	for (cnt = 0; cnt < size;) {
26873ce8866cSSaurav Kashyap 		c = *b++;
26883ce8866cSSaurav Kashyap 		printk("%02x", (uint32_t) c);
26893ce8866cSSaurav Kashyap 		cnt++;
26903ce8866cSSaurav Kashyap 		if (!(cnt % 16))
26913ce8866cSSaurav Kashyap 			printk("\n");
26923ce8866cSSaurav Kashyap 		else
26933ce8866cSSaurav Kashyap 			printk("  ");
26943ce8866cSSaurav Kashyap 	}
26953ce8866cSSaurav Kashyap 	if (cnt % 16)
26963ce8866cSSaurav Kashyap 		ql_dbg(level, vha, id, "\n");
26973ce8866cSSaurav Kashyap }
2698