1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * QLogic Fibre Channel HBA Driver
4*4882a593Smuzhiyun * Copyright (c) 2003-2014 QLogic Corporation
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun /*
8*4882a593Smuzhiyun * Table for showing the current message id in use for particular level
9*4882a593Smuzhiyun * Change this table for addition of log/debug messages.
10*4882a593Smuzhiyun * ----------------------------------------------------------------------
11*4882a593Smuzhiyun * | Level | Last Value Used | Holes |
12*4882a593Smuzhiyun * ----------------------------------------------------------------------
13*4882a593Smuzhiyun * | Module Init and Probe | 0x0199 | |
14*4882a593Smuzhiyun * | Mailbox commands | 0x1206 | 0x11a5-0x11ff |
15*4882a593Smuzhiyun * | Device Discovery | 0x2134 | 0x210e-0x2115 |
16*4882a593Smuzhiyun * | | | 0x211c-0x2128 |
17*4882a593Smuzhiyun * | | | 0x212c-0x2134 |
18*4882a593Smuzhiyun * | Queue Command and IO tracing | 0x3074 | 0x300b |
19*4882a593Smuzhiyun * | | | 0x3027-0x3028 |
20*4882a593Smuzhiyun * | | | 0x303d-0x3041 |
21*4882a593Smuzhiyun * | | | 0x302d,0x3033 |
22*4882a593Smuzhiyun * | | | 0x3036,0x3038 |
23*4882a593Smuzhiyun * | | | 0x303a |
24*4882a593Smuzhiyun * | DPC Thread | 0x4023 | 0x4002,0x4013 |
25*4882a593Smuzhiyun * | Async Events | 0x509c | |
26*4882a593Smuzhiyun * | Timer Routines | 0x6012 | |
27*4882a593Smuzhiyun * | User Space Interactions | 0x70e3 | 0x7018,0x702e |
28*4882a593Smuzhiyun * | | | 0x7020,0x7024 |
29*4882a593Smuzhiyun * | | | 0x7039,0x7045 |
30*4882a593Smuzhiyun * | | | 0x7073-0x7075 |
31*4882a593Smuzhiyun * | | | 0x70a5-0x70a6 |
32*4882a593Smuzhiyun * | | | 0x70a8,0x70ab |
33*4882a593Smuzhiyun * | | | 0x70ad-0x70ae |
34*4882a593Smuzhiyun * | | | 0x70d0-0x70d6 |
35*4882a593Smuzhiyun * | | | 0x70d7-0x70db |
36*4882a593Smuzhiyun * | Task Management | 0x8042 | 0x8000 |
37*4882a593Smuzhiyun * | | | 0x8019 |
38*4882a593Smuzhiyun * | | | 0x8025,0x8026 |
39*4882a593Smuzhiyun * | | | 0x8031,0x8032 |
40*4882a593Smuzhiyun * | | | 0x8039,0x803c |
41*4882a593Smuzhiyun * | AER/EEH | 0x9011 | |
42*4882a593Smuzhiyun * | Virtual Port | 0xa007 | |
43*4882a593Smuzhiyun * | ISP82XX Specific | 0xb157 | 0xb002,0xb024 |
44*4882a593Smuzhiyun * | | | 0xb09e,0xb0ae |
45*4882a593Smuzhiyun * | | | 0xb0c3,0xb0c6 |
46*4882a593Smuzhiyun * | | | 0xb0e0-0xb0ef |
47*4882a593Smuzhiyun * | | | 0xb085,0xb0dc |
48*4882a593Smuzhiyun * | | | 0xb107,0xb108 |
49*4882a593Smuzhiyun * | | | 0xb111,0xb11e |
50*4882a593Smuzhiyun * | | | 0xb12c,0xb12d |
51*4882a593Smuzhiyun * | | | 0xb13a,0xb142 |
52*4882a593Smuzhiyun * | | | 0xb13c-0xb140 |
53*4882a593Smuzhiyun * | | | 0xb149 |
54*4882a593Smuzhiyun * | MultiQ | 0xc010 | |
55*4882a593Smuzhiyun * | Misc | 0xd303 | 0xd031-0xd0ff |
56*4882a593Smuzhiyun * | | | 0xd101-0xd1fe |
57*4882a593Smuzhiyun * | | | 0xd214-0xd2fe |
58*4882a593Smuzhiyun * | Target Mode | 0xe081 | |
59*4882a593Smuzhiyun * | Target Mode Management | 0xf09b | 0xf002 |
60*4882a593Smuzhiyun * | | | 0xf046-0xf049 |
61*4882a593Smuzhiyun * | Target Mode Task Management | 0x1000d | |
62*4882a593Smuzhiyun * ----------------------------------------------------------------------
63*4882a593Smuzhiyun */
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun #include "qla_def.h"
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun #include <linux/delay.h>
68*4882a593Smuzhiyun #define CREATE_TRACE_POINTS
69*4882a593Smuzhiyun #include <trace/events/qla.h>
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun static uint32_t ql_dbg_offset = 0x800;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun static inline void
qla2xxx_prep_dump(struct qla_hw_data * ha,struct qla2xxx_fw_dump * fw_dump)74*4882a593Smuzhiyun qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun fw_dump->fw_major_version = htonl(ha->fw_major_version);
77*4882a593Smuzhiyun fw_dump->fw_minor_version = htonl(ha->fw_minor_version);
78*4882a593Smuzhiyun fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version);
79*4882a593Smuzhiyun fw_dump->fw_attributes = htonl(ha->fw_attributes);
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun fw_dump->vendor = htonl(ha->pdev->vendor);
82*4882a593Smuzhiyun fw_dump->device = htonl(ha->pdev->device);
83*4882a593Smuzhiyun fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor);
84*4882a593Smuzhiyun fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device);
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun static inline void *
qla2xxx_copy_queues(struct qla_hw_data * ha,void * ptr)88*4882a593Smuzhiyun qla2xxx_copy_queues(struct qla_hw_data *ha, void *ptr)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun struct req_que *req = ha->req_q_map[0];
91*4882a593Smuzhiyun struct rsp_que *rsp = ha->rsp_q_map[0];
92*4882a593Smuzhiyun /* Request queue. */
93*4882a593Smuzhiyun memcpy(ptr, req->ring, req->length *
94*4882a593Smuzhiyun sizeof(request_t));
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun /* Response queue. */
97*4882a593Smuzhiyun ptr += req->length * sizeof(request_t);
98*4882a593Smuzhiyun memcpy(ptr, rsp->ring, rsp->length *
99*4882a593Smuzhiyun sizeof(response_t));
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun return ptr + (rsp->length * sizeof(response_t));
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun int
qla27xx_dump_mpi_ram(struct qla_hw_data * ha,uint32_t addr,uint32_t * ram,uint32_t ram_dwords,void ** nxt)105*4882a593Smuzhiyun qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
106*4882a593Smuzhiyun uint32_t ram_dwords, void **nxt)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
109*4882a593Smuzhiyun dma_addr_t dump_dma = ha->gid_list_dma;
110*4882a593Smuzhiyun uint32_t *chunk = (uint32_t *)ha->gid_list;
111*4882a593Smuzhiyun uint32_t dwords = qla2x00_gid_list_size(ha) / 4;
112*4882a593Smuzhiyun uint32_t stat;
113*4882a593Smuzhiyun ulong i, j, timer = 6000000;
114*4882a593Smuzhiyun int rval = QLA_FUNCTION_FAILED;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
117*4882a593Smuzhiyun for (i = 0; i < ram_dwords; i += dwords, addr += dwords) {
118*4882a593Smuzhiyun if (i + dwords > ram_dwords)
119*4882a593Smuzhiyun dwords = ram_dwords - i;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun wrt_reg_word(®->mailbox0, MBC_LOAD_DUMP_MPI_RAM);
122*4882a593Smuzhiyun wrt_reg_word(®->mailbox1, LSW(addr));
123*4882a593Smuzhiyun wrt_reg_word(®->mailbox8, MSW(addr));
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun wrt_reg_word(®->mailbox2, MSW(LSD(dump_dma)));
126*4882a593Smuzhiyun wrt_reg_word(®->mailbox3, LSW(LSD(dump_dma)));
127*4882a593Smuzhiyun wrt_reg_word(®->mailbox6, MSW(MSD(dump_dma)));
128*4882a593Smuzhiyun wrt_reg_word(®->mailbox7, LSW(MSD(dump_dma)));
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun wrt_reg_word(®->mailbox4, MSW(dwords));
131*4882a593Smuzhiyun wrt_reg_word(®->mailbox5, LSW(dwords));
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun wrt_reg_word(®->mailbox9, 0);
134*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_SET_HOST_INT);
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun ha->flags.mbox_int = 0;
137*4882a593Smuzhiyun while (timer--) {
138*4882a593Smuzhiyun udelay(5);
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun stat = rd_reg_dword(®->host_status);
141*4882a593Smuzhiyun /* Check for pending interrupts. */
142*4882a593Smuzhiyun if (!(stat & HSRX_RISC_INT))
143*4882a593Smuzhiyun continue;
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun stat &= 0xff;
146*4882a593Smuzhiyun if (stat != 0x1 && stat != 0x2 &&
147*4882a593Smuzhiyun stat != 0x10 && stat != 0x11) {
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /* Clear this intr; it wasn't a mailbox intr */
150*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT);
151*4882a593Smuzhiyun rd_reg_dword(®->hccr);
152*4882a593Smuzhiyun continue;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
156*4882a593Smuzhiyun rval = rd_reg_word(®->mailbox0) & MBS_MASK;
157*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT);
158*4882a593Smuzhiyun rd_reg_dword(®->hccr);
159*4882a593Smuzhiyun break;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun ha->flags.mbox_int = 1;
162*4882a593Smuzhiyun *nxt = ram + i;
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun if (!test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
165*4882a593Smuzhiyun /* no interrupt, timed out*/
166*4882a593Smuzhiyun return rval;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun if (rval) {
169*4882a593Smuzhiyun /* error completion status */
170*4882a593Smuzhiyun return rval;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun for (j = 0; j < dwords; j++) {
173*4882a593Smuzhiyun ram[i + j] =
174*4882a593Smuzhiyun (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ?
175*4882a593Smuzhiyun chunk[j] : swab32(chunk[j]);
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun *nxt = ram + i;
180*4882a593Smuzhiyun return QLA_SUCCESS;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun int
qla24xx_dump_ram(struct qla_hw_data * ha,uint32_t addr,__be32 * ram,uint32_t ram_dwords,void ** nxt)184*4882a593Smuzhiyun qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be32 *ram,
185*4882a593Smuzhiyun uint32_t ram_dwords, void **nxt)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun int rval = QLA_FUNCTION_FAILED;
188*4882a593Smuzhiyun struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
189*4882a593Smuzhiyun dma_addr_t dump_dma = ha->gid_list_dma;
190*4882a593Smuzhiyun uint32_t *chunk = (uint32_t *)ha->gid_list;
191*4882a593Smuzhiyun uint32_t dwords = qla2x00_gid_list_size(ha) / 4;
192*4882a593Smuzhiyun uint32_t stat;
193*4882a593Smuzhiyun ulong i, j, timer = 6000000;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun for (i = 0; i < ram_dwords; i += dwords, addr += dwords) {
198*4882a593Smuzhiyun if (i + dwords > ram_dwords)
199*4882a593Smuzhiyun dwords = ram_dwords - i;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun wrt_reg_word(®->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED);
202*4882a593Smuzhiyun wrt_reg_word(®->mailbox1, LSW(addr));
203*4882a593Smuzhiyun wrt_reg_word(®->mailbox8, MSW(addr));
204*4882a593Smuzhiyun wrt_reg_word(®->mailbox10, 0);
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun wrt_reg_word(®->mailbox2, MSW(LSD(dump_dma)));
207*4882a593Smuzhiyun wrt_reg_word(®->mailbox3, LSW(LSD(dump_dma)));
208*4882a593Smuzhiyun wrt_reg_word(®->mailbox6, MSW(MSD(dump_dma)));
209*4882a593Smuzhiyun wrt_reg_word(®->mailbox7, LSW(MSD(dump_dma)));
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun wrt_reg_word(®->mailbox4, MSW(dwords));
212*4882a593Smuzhiyun wrt_reg_word(®->mailbox5, LSW(dwords));
213*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_SET_HOST_INT);
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun ha->flags.mbox_int = 0;
216*4882a593Smuzhiyun while (timer--) {
217*4882a593Smuzhiyun udelay(5);
218*4882a593Smuzhiyun stat = rd_reg_dword(®->host_status);
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun /* Check for pending interrupts. */
221*4882a593Smuzhiyun if (!(stat & HSRX_RISC_INT))
222*4882a593Smuzhiyun continue;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun stat &= 0xff;
225*4882a593Smuzhiyun if (stat != 0x1 && stat != 0x2 &&
226*4882a593Smuzhiyun stat != 0x10 && stat != 0x11) {
227*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT);
228*4882a593Smuzhiyun rd_reg_dword(®->hccr);
229*4882a593Smuzhiyun continue;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
233*4882a593Smuzhiyun rval = rd_reg_word(®->mailbox0) & MBS_MASK;
234*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT);
235*4882a593Smuzhiyun rd_reg_dword(®->hccr);
236*4882a593Smuzhiyun break;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun ha->flags.mbox_int = 1;
239*4882a593Smuzhiyun *nxt = ram + i;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun if (!test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
242*4882a593Smuzhiyun /* no interrupt, timed out*/
243*4882a593Smuzhiyun return rval;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun if (rval) {
246*4882a593Smuzhiyun /* error completion status */
247*4882a593Smuzhiyun return rval;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun for (j = 0; j < dwords; j++) {
250*4882a593Smuzhiyun ram[i + j] = (__force __be32)
251*4882a593Smuzhiyun ((IS_QLA27XX(ha) || IS_QLA28XX(ha)) ?
252*4882a593Smuzhiyun chunk[j] : swab32(chunk[j]));
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun *nxt = ram + i;
257*4882a593Smuzhiyun return QLA_SUCCESS;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun static int
qla24xx_dump_memory(struct qla_hw_data * ha,__be32 * code_ram,uint32_t cram_size,void ** nxt)261*4882a593Smuzhiyun qla24xx_dump_memory(struct qla_hw_data *ha, __be32 *code_ram,
262*4882a593Smuzhiyun uint32_t cram_size, void **nxt)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun int rval;
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun /* Code RAM. */
267*4882a593Smuzhiyun rval = qla24xx_dump_ram(ha, 0x20000, code_ram, cram_size / 4, nxt);
268*4882a593Smuzhiyun if (rval != QLA_SUCCESS)
269*4882a593Smuzhiyun return rval;
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun set_bit(RISC_SRAM_DUMP_CMPL, &ha->fw_dump_cap_flags);
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun /* External Memory. */
274*4882a593Smuzhiyun rval = qla24xx_dump_ram(ha, 0x100000, *nxt,
275*4882a593Smuzhiyun ha->fw_memory_size - 0x100000 + 1, nxt);
276*4882a593Smuzhiyun if (rval == QLA_SUCCESS)
277*4882a593Smuzhiyun set_bit(RISC_EXT_MEM_DUMP_CMPL, &ha->fw_dump_cap_flags);
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun return rval;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun static __be32 *
qla24xx_read_window(struct device_reg_24xx __iomem * reg,uint32_t iobase,uint32_t count,__be32 * buf)283*4882a593Smuzhiyun qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase,
284*4882a593Smuzhiyun uint32_t count, __be32 *buf)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun __le32 __iomem *dmp_reg;
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, iobase);
289*4882a593Smuzhiyun dmp_reg = ®->iobase_window;
290*4882a593Smuzhiyun for ( ; count--; dmp_reg++)
291*4882a593Smuzhiyun *buf++ = htonl(rd_reg_dword(dmp_reg));
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun return buf;
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun void
qla24xx_pause_risc(struct device_reg_24xx __iomem * reg,struct qla_hw_data * ha)297*4882a593Smuzhiyun qla24xx_pause_risc(struct device_reg_24xx __iomem *reg, struct qla_hw_data *ha)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_SET_RISC_PAUSE);
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun /* 100 usec delay is sufficient enough for hardware to pause RISC */
302*4882a593Smuzhiyun udelay(100);
303*4882a593Smuzhiyun if (rd_reg_dword(®->host_status) & HSRX_RISC_PAUSED)
304*4882a593Smuzhiyun set_bit(RISC_PAUSE_CMPL, &ha->fw_dump_cap_flags);
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun int
qla24xx_soft_reset(struct qla_hw_data * ha)308*4882a593Smuzhiyun qla24xx_soft_reset(struct qla_hw_data *ha)
309*4882a593Smuzhiyun {
310*4882a593Smuzhiyun int rval = QLA_SUCCESS;
311*4882a593Smuzhiyun uint32_t cnt;
312*4882a593Smuzhiyun uint16_t wd;
313*4882a593Smuzhiyun struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun /*
316*4882a593Smuzhiyun * Reset RISC. The delay is dependent on system architecture.
317*4882a593Smuzhiyun * Driver can proceed with the reset sequence after waiting
318*4882a593Smuzhiyun * for a timeout period.
319*4882a593Smuzhiyun */
320*4882a593Smuzhiyun wrt_reg_dword(®->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
321*4882a593Smuzhiyun for (cnt = 0; cnt < 30000; cnt++) {
322*4882a593Smuzhiyun if ((rd_reg_dword(®->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
323*4882a593Smuzhiyun break;
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun udelay(10);
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun if (!(rd_reg_dword(®->ctrl_status) & CSRX_DMA_ACTIVE))
328*4882a593Smuzhiyun set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags);
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun wrt_reg_dword(®->ctrl_status,
331*4882a593Smuzhiyun CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
332*4882a593Smuzhiyun pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun udelay(100);
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun /* Wait for soft-reset to complete. */
337*4882a593Smuzhiyun for (cnt = 0; cnt < 30000; cnt++) {
338*4882a593Smuzhiyun if ((rd_reg_dword(®->ctrl_status) &
339*4882a593Smuzhiyun CSRX_ISP_SOFT_RESET) == 0)
340*4882a593Smuzhiyun break;
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun udelay(10);
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun if (!(rd_reg_dword(®->ctrl_status) & CSRX_ISP_SOFT_RESET))
345*4882a593Smuzhiyun set_bit(ISP_RESET_CMPL, &ha->fw_dump_cap_flags);
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_RESET);
348*4882a593Smuzhiyun rd_reg_dword(®->hccr); /* PCI Posting. */
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun for (cnt = 10000; rd_reg_word(®->mailbox0) != 0 &&
351*4882a593Smuzhiyun rval == QLA_SUCCESS; cnt--) {
352*4882a593Smuzhiyun if (cnt)
353*4882a593Smuzhiyun udelay(10);
354*4882a593Smuzhiyun else
355*4882a593Smuzhiyun rval = QLA_FUNCTION_TIMEOUT;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun if (rval == QLA_SUCCESS)
358*4882a593Smuzhiyun set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun return rval;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun static int
qla2xxx_dump_ram(struct qla_hw_data * ha,uint32_t addr,__be16 * ram,uint32_t ram_words,void ** nxt)364*4882a593Smuzhiyun qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be16 *ram,
365*4882a593Smuzhiyun uint32_t ram_words, void **nxt)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun int rval;
368*4882a593Smuzhiyun uint32_t cnt, stat, timer, words, idx;
369*4882a593Smuzhiyun uint16_t mb0;
370*4882a593Smuzhiyun struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
371*4882a593Smuzhiyun dma_addr_t dump_dma = ha->gid_list_dma;
372*4882a593Smuzhiyun __le16 *dump = (__force __le16 *)ha->gid_list;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun rval = QLA_SUCCESS;
375*4882a593Smuzhiyun mb0 = 0;
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun WRT_MAILBOX_REG(ha, reg, 0, MBC_DUMP_RISC_RAM_EXTENDED);
378*4882a593Smuzhiyun clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun words = qla2x00_gid_list_size(ha) / 2;
381*4882a593Smuzhiyun for (cnt = 0; cnt < ram_words && rval == QLA_SUCCESS;
382*4882a593Smuzhiyun cnt += words, addr += words) {
383*4882a593Smuzhiyun if (cnt + words > ram_words)
384*4882a593Smuzhiyun words = ram_words - cnt;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun WRT_MAILBOX_REG(ha, reg, 1, LSW(addr));
387*4882a593Smuzhiyun WRT_MAILBOX_REG(ha, reg, 8, MSW(addr));
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun WRT_MAILBOX_REG(ha, reg, 2, MSW(dump_dma));
390*4882a593Smuzhiyun WRT_MAILBOX_REG(ha, reg, 3, LSW(dump_dma));
391*4882a593Smuzhiyun WRT_MAILBOX_REG(ha, reg, 6, MSW(MSD(dump_dma)));
392*4882a593Smuzhiyun WRT_MAILBOX_REG(ha, reg, 7, LSW(MSD(dump_dma)));
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun WRT_MAILBOX_REG(ha, reg, 4, words);
395*4882a593Smuzhiyun wrt_reg_word(®->hccr, HCCR_SET_HOST_INT);
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun for (timer = 6000000; timer; timer--) {
398*4882a593Smuzhiyun /* Check for pending interrupts. */
399*4882a593Smuzhiyun stat = rd_reg_dword(®->u.isp2300.host_status);
400*4882a593Smuzhiyun if (stat & HSR_RISC_INT) {
401*4882a593Smuzhiyun stat &= 0xff;
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun if (stat == 0x1 || stat == 0x2) {
404*4882a593Smuzhiyun set_bit(MBX_INTERRUPT,
405*4882a593Smuzhiyun &ha->mbx_cmd_flags);
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun mb0 = RD_MAILBOX_REG(ha, reg, 0);
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun /* Release mailbox registers. */
410*4882a593Smuzhiyun wrt_reg_word(®->semaphore, 0);
411*4882a593Smuzhiyun wrt_reg_word(®->hccr,
412*4882a593Smuzhiyun HCCR_CLR_RISC_INT);
413*4882a593Smuzhiyun rd_reg_word(®->hccr);
414*4882a593Smuzhiyun break;
415*4882a593Smuzhiyun } else if (stat == 0x10 || stat == 0x11) {
416*4882a593Smuzhiyun set_bit(MBX_INTERRUPT,
417*4882a593Smuzhiyun &ha->mbx_cmd_flags);
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun mb0 = RD_MAILBOX_REG(ha, reg, 0);
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun wrt_reg_word(®->hccr,
422*4882a593Smuzhiyun HCCR_CLR_RISC_INT);
423*4882a593Smuzhiyun rd_reg_word(®->hccr);
424*4882a593Smuzhiyun break;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun /* clear this intr; it wasn't a mailbox intr */
428*4882a593Smuzhiyun wrt_reg_word(®->hccr, HCCR_CLR_RISC_INT);
429*4882a593Smuzhiyun rd_reg_word(®->hccr);
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun udelay(5);
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
435*4882a593Smuzhiyun rval = mb0 & MBS_MASK;
436*4882a593Smuzhiyun for (idx = 0; idx < words; idx++)
437*4882a593Smuzhiyun ram[cnt + idx] =
438*4882a593Smuzhiyun cpu_to_be16(le16_to_cpu(dump[idx]));
439*4882a593Smuzhiyun } else {
440*4882a593Smuzhiyun rval = QLA_FUNCTION_FAILED;
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun *nxt = rval == QLA_SUCCESS ? &ram[cnt] : NULL;
445*4882a593Smuzhiyun return rval;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun static inline void
qla2xxx_read_window(struct device_reg_2xxx __iomem * reg,uint32_t count,__be16 * buf)449*4882a593Smuzhiyun qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count,
450*4882a593Smuzhiyun __be16 *buf)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun __le16 __iomem *dmp_reg = ®->u.isp2300.fb_cmd;
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun for ( ; count--; dmp_reg++)
455*4882a593Smuzhiyun *buf++ = htons(rd_reg_word(dmp_reg));
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun static inline void *
qla24xx_copy_eft(struct qla_hw_data * ha,void * ptr)459*4882a593Smuzhiyun qla24xx_copy_eft(struct qla_hw_data *ha, void *ptr)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun if (!ha->eft)
462*4882a593Smuzhiyun return ptr;
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun memcpy(ptr, ha->eft, ntohl(ha->fw_dump->eft_size));
465*4882a593Smuzhiyun return ptr + ntohl(ha->fw_dump->eft_size);
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun static inline void *
qla25xx_copy_fce(struct qla_hw_data * ha,void * ptr,__be32 ** last_chain)469*4882a593Smuzhiyun qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, __be32 **last_chain)
470*4882a593Smuzhiyun {
471*4882a593Smuzhiyun uint32_t cnt;
472*4882a593Smuzhiyun __be32 *iter_reg;
473*4882a593Smuzhiyun struct qla2xxx_fce_chain *fcec = ptr;
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun if (!ha->fce)
476*4882a593Smuzhiyun return ptr;
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun *last_chain = &fcec->type;
479*4882a593Smuzhiyun fcec->type = htonl(DUMP_CHAIN_FCE);
480*4882a593Smuzhiyun fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) +
481*4882a593Smuzhiyun fce_calc_size(ha->fce_bufs));
482*4882a593Smuzhiyun fcec->size = htonl(fce_calc_size(ha->fce_bufs));
483*4882a593Smuzhiyun fcec->addr_l = htonl(LSD(ha->fce_dma));
484*4882a593Smuzhiyun fcec->addr_h = htonl(MSD(ha->fce_dma));
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun iter_reg = fcec->eregs;
487*4882a593Smuzhiyun for (cnt = 0; cnt < 8; cnt++)
488*4882a593Smuzhiyun *iter_reg++ = htonl(ha->fce_mb[cnt]);
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun memcpy(iter_reg, ha->fce, ntohl(fcec->size));
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun return (char *)iter_reg + ntohl(fcec->size);
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun static inline void *
qla25xx_copy_exlogin(struct qla_hw_data * ha,void * ptr,__be32 ** last_chain)496*4882a593Smuzhiyun qla25xx_copy_exlogin(struct qla_hw_data *ha, void *ptr, __be32 **last_chain)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun struct qla2xxx_offld_chain *c = ptr;
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun if (!ha->exlogin_buf)
501*4882a593Smuzhiyun return ptr;
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun *last_chain = &c->type;
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun c->type = cpu_to_be32(DUMP_CHAIN_EXLOGIN);
506*4882a593Smuzhiyun c->chain_size = cpu_to_be32(sizeof(struct qla2xxx_offld_chain) +
507*4882a593Smuzhiyun ha->exlogin_size);
508*4882a593Smuzhiyun c->size = cpu_to_be32(ha->exlogin_size);
509*4882a593Smuzhiyun c->addr = cpu_to_be64(ha->exlogin_buf_dma);
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun ptr += sizeof(struct qla2xxx_offld_chain);
512*4882a593Smuzhiyun memcpy(ptr, ha->exlogin_buf, ha->exlogin_size);
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun return (char *)ptr + be32_to_cpu(c->size);
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun static inline void *
qla81xx_copy_exchoffld(struct qla_hw_data * ha,void * ptr,__be32 ** last_chain)518*4882a593Smuzhiyun qla81xx_copy_exchoffld(struct qla_hw_data *ha, void *ptr, __be32 **last_chain)
519*4882a593Smuzhiyun {
520*4882a593Smuzhiyun struct qla2xxx_offld_chain *c = ptr;
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun if (!ha->exchoffld_buf)
523*4882a593Smuzhiyun return ptr;
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun *last_chain = &c->type;
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun c->type = cpu_to_be32(DUMP_CHAIN_EXCHG);
528*4882a593Smuzhiyun c->chain_size = cpu_to_be32(sizeof(struct qla2xxx_offld_chain) +
529*4882a593Smuzhiyun ha->exchoffld_size);
530*4882a593Smuzhiyun c->size = cpu_to_be32(ha->exchoffld_size);
531*4882a593Smuzhiyun c->addr = cpu_to_be64(ha->exchoffld_buf_dma);
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun ptr += sizeof(struct qla2xxx_offld_chain);
534*4882a593Smuzhiyun memcpy(ptr, ha->exchoffld_buf, ha->exchoffld_size);
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun return (char *)ptr + be32_to_cpu(c->size);
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun static inline void *
qla2xxx_copy_atioqueues(struct qla_hw_data * ha,void * ptr,__be32 ** last_chain)540*4882a593Smuzhiyun qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr,
541*4882a593Smuzhiyun __be32 **last_chain)
542*4882a593Smuzhiyun {
543*4882a593Smuzhiyun struct qla2xxx_mqueue_chain *q;
544*4882a593Smuzhiyun struct qla2xxx_mqueue_header *qh;
545*4882a593Smuzhiyun uint32_t num_queues;
546*4882a593Smuzhiyun int que;
547*4882a593Smuzhiyun struct {
548*4882a593Smuzhiyun int length;
549*4882a593Smuzhiyun void *ring;
550*4882a593Smuzhiyun } aq, *aqp;
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun if (!ha->tgt.atio_ring)
553*4882a593Smuzhiyun return ptr;
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun num_queues = 1;
556*4882a593Smuzhiyun aqp = &aq;
557*4882a593Smuzhiyun aqp->length = ha->tgt.atio_q_length;
558*4882a593Smuzhiyun aqp->ring = ha->tgt.atio_ring;
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun for (que = 0; que < num_queues; que++) {
561*4882a593Smuzhiyun /* aqp = ha->atio_q_map[que]; */
562*4882a593Smuzhiyun q = ptr;
563*4882a593Smuzhiyun *last_chain = &q->type;
564*4882a593Smuzhiyun q->type = htonl(DUMP_CHAIN_QUEUE);
565*4882a593Smuzhiyun q->chain_size = htonl(
566*4882a593Smuzhiyun sizeof(struct qla2xxx_mqueue_chain) +
567*4882a593Smuzhiyun sizeof(struct qla2xxx_mqueue_header) +
568*4882a593Smuzhiyun (aqp->length * sizeof(request_t)));
569*4882a593Smuzhiyun ptr += sizeof(struct qla2xxx_mqueue_chain);
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun /* Add header. */
572*4882a593Smuzhiyun qh = ptr;
573*4882a593Smuzhiyun qh->queue = htonl(TYPE_ATIO_QUEUE);
574*4882a593Smuzhiyun qh->number = htonl(que);
575*4882a593Smuzhiyun qh->size = htonl(aqp->length * sizeof(request_t));
576*4882a593Smuzhiyun ptr += sizeof(struct qla2xxx_mqueue_header);
577*4882a593Smuzhiyun
578*4882a593Smuzhiyun /* Add data. */
579*4882a593Smuzhiyun memcpy(ptr, aqp->ring, aqp->length * sizeof(request_t));
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun ptr += aqp->length * sizeof(request_t);
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun return ptr;
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun static inline void *
qla25xx_copy_mqueues(struct qla_hw_data * ha,void * ptr,__be32 ** last_chain)588*4882a593Smuzhiyun qla25xx_copy_mqueues(struct qla_hw_data *ha, void *ptr, __be32 **last_chain)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun struct qla2xxx_mqueue_chain *q;
591*4882a593Smuzhiyun struct qla2xxx_mqueue_header *qh;
592*4882a593Smuzhiyun struct req_que *req;
593*4882a593Smuzhiyun struct rsp_que *rsp;
594*4882a593Smuzhiyun int que;
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun if (!ha->mqenable)
597*4882a593Smuzhiyun return ptr;
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun /* Request queues */
600*4882a593Smuzhiyun for (que = 1; que < ha->max_req_queues; que++) {
601*4882a593Smuzhiyun req = ha->req_q_map[que];
602*4882a593Smuzhiyun if (!req)
603*4882a593Smuzhiyun break;
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun /* Add chain. */
606*4882a593Smuzhiyun q = ptr;
607*4882a593Smuzhiyun *last_chain = &q->type;
608*4882a593Smuzhiyun q->type = htonl(DUMP_CHAIN_QUEUE);
609*4882a593Smuzhiyun q->chain_size = htonl(
610*4882a593Smuzhiyun sizeof(struct qla2xxx_mqueue_chain) +
611*4882a593Smuzhiyun sizeof(struct qla2xxx_mqueue_header) +
612*4882a593Smuzhiyun (req->length * sizeof(request_t)));
613*4882a593Smuzhiyun ptr += sizeof(struct qla2xxx_mqueue_chain);
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun /* Add header. */
616*4882a593Smuzhiyun qh = ptr;
617*4882a593Smuzhiyun qh->queue = htonl(TYPE_REQUEST_QUEUE);
618*4882a593Smuzhiyun qh->number = htonl(que);
619*4882a593Smuzhiyun qh->size = htonl(req->length * sizeof(request_t));
620*4882a593Smuzhiyun ptr += sizeof(struct qla2xxx_mqueue_header);
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun /* Add data. */
623*4882a593Smuzhiyun memcpy(ptr, req->ring, req->length * sizeof(request_t));
624*4882a593Smuzhiyun ptr += req->length * sizeof(request_t);
625*4882a593Smuzhiyun }
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun /* Response queues */
628*4882a593Smuzhiyun for (que = 1; que < ha->max_rsp_queues; que++) {
629*4882a593Smuzhiyun rsp = ha->rsp_q_map[que];
630*4882a593Smuzhiyun if (!rsp)
631*4882a593Smuzhiyun break;
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun /* Add chain. */
634*4882a593Smuzhiyun q = ptr;
635*4882a593Smuzhiyun *last_chain = &q->type;
636*4882a593Smuzhiyun q->type = htonl(DUMP_CHAIN_QUEUE);
637*4882a593Smuzhiyun q->chain_size = htonl(
638*4882a593Smuzhiyun sizeof(struct qla2xxx_mqueue_chain) +
639*4882a593Smuzhiyun sizeof(struct qla2xxx_mqueue_header) +
640*4882a593Smuzhiyun (rsp->length * sizeof(response_t)));
641*4882a593Smuzhiyun ptr += sizeof(struct qla2xxx_mqueue_chain);
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun /* Add header. */
644*4882a593Smuzhiyun qh = ptr;
645*4882a593Smuzhiyun qh->queue = htonl(TYPE_RESPONSE_QUEUE);
646*4882a593Smuzhiyun qh->number = htonl(que);
647*4882a593Smuzhiyun qh->size = htonl(rsp->length * sizeof(response_t));
648*4882a593Smuzhiyun ptr += sizeof(struct qla2xxx_mqueue_header);
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun /* Add data. */
651*4882a593Smuzhiyun memcpy(ptr, rsp->ring, rsp->length * sizeof(response_t));
652*4882a593Smuzhiyun ptr += rsp->length * sizeof(response_t);
653*4882a593Smuzhiyun }
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun return ptr;
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun
658*4882a593Smuzhiyun static inline void *
qla25xx_copy_mq(struct qla_hw_data * ha,void * ptr,__be32 ** last_chain)659*4882a593Smuzhiyun qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, __be32 **last_chain)
660*4882a593Smuzhiyun {
661*4882a593Smuzhiyun uint32_t cnt, que_idx;
662*4882a593Smuzhiyun uint8_t que_cnt;
663*4882a593Smuzhiyun struct qla2xxx_mq_chain *mq = ptr;
664*4882a593Smuzhiyun device_reg_t *reg;
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun if (!ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
667*4882a593Smuzhiyun IS_QLA28XX(ha))
668*4882a593Smuzhiyun return ptr;
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun mq = ptr;
671*4882a593Smuzhiyun *last_chain = &mq->type;
672*4882a593Smuzhiyun mq->type = htonl(DUMP_CHAIN_MQ);
673*4882a593Smuzhiyun mq->chain_size = htonl(sizeof(struct qla2xxx_mq_chain));
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun que_cnt = ha->max_req_queues > ha->max_rsp_queues ?
676*4882a593Smuzhiyun ha->max_req_queues : ha->max_rsp_queues;
677*4882a593Smuzhiyun mq->count = htonl(que_cnt);
678*4882a593Smuzhiyun for (cnt = 0; cnt < que_cnt; cnt++) {
679*4882a593Smuzhiyun reg = ISP_QUE_REG(ha, cnt);
680*4882a593Smuzhiyun que_idx = cnt * 4;
681*4882a593Smuzhiyun mq->qregs[que_idx] =
682*4882a593Smuzhiyun htonl(rd_reg_dword(®->isp25mq.req_q_in));
683*4882a593Smuzhiyun mq->qregs[que_idx+1] =
684*4882a593Smuzhiyun htonl(rd_reg_dword(®->isp25mq.req_q_out));
685*4882a593Smuzhiyun mq->qregs[que_idx+2] =
686*4882a593Smuzhiyun htonl(rd_reg_dword(®->isp25mq.rsp_q_in));
687*4882a593Smuzhiyun mq->qregs[que_idx+3] =
688*4882a593Smuzhiyun htonl(rd_reg_dword(®->isp25mq.rsp_q_out));
689*4882a593Smuzhiyun }
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun return ptr + sizeof(struct qla2xxx_mq_chain);
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun void
qla2xxx_dump_post_process(scsi_qla_host_t * vha,int rval)695*4882a593Smuzhiyun qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
696*4882a593Smuzhiyun {
697*4882a593Smuzhiyun struct qla_hw_data *ha = vha->hw;
698*4882a593Smuzhiyun
699*4882a593Smuzhiyun if (rval != QLA_SUCCESS) {
700*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd000,
701*4882a593Smuzhiyun "Failed to dump firmware (%x), dump status flags (0x%lx).\n",
702*4882a593Smuzhiyun rval, ha->fw_dump_cap_flags);
703*4882a593Smuzhiyun ha->fw_dumped = false;
704*4882a593Smuzhiyun } else {
705*4882a593Smuzhiyun ql_log(ql_log_info, vha, 0xd001,
706*4882a593Smuzhiyun "Firmware dump saved to temp buffer (%ld/%p), dump status flags (0x%lx).\n",
707*4882a593Smuzhiyun vha->host_no, ha->fw_dump, ha->fw_dump_cap_flags);
708*4882a593Smuzhiyun ha->fw_dumped = true;
709*4882a593Smuzhiyun qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun
qla2xxx_dump_fw(scsi_qla_host_t * vha)713*4882a593Smuzhiyun void qla2xxx_dump_fw(scsi_qla_host_t *vha)
714*4882a593Smuzhiyun {
715*4882a593Smuzhiyun unsigned long flags;
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun spin_lock_irqsave(&vha->hw->hardware_lock, flags);
718*4882a593Smuzhiyun vha->hw->isp_ops->fw_dump(vha);
719*4882a593Smuzhiyun spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
720*4882a593Smuzhiyun }
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun /**
723*4882a593Smuzhiyun * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
724*4882a593Smuzhiyun * @vha: HA context
725*4882a593Smuzhiyun */
726*4882a593Smuzhiyun void
qla2300_fw_dump(scsi_qla_host_t * vha)727*4882a593Smuzhiyun qla2300_fw_dump(scsi_qla_host_t *vha)
728*4882a593Smuzhiyun {
729*4882a593Smuzhiyun int rval;
730*4882a593Smuzhiyun uint32_t cnt;
731*4882a593Smuzhiyun struct qla_hw_data *ha = vha->hw;
732*4882a593Smuzhiyun struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
733*4882a593Smuzhiyun __le16 __iomem *dmp_reg;
734*4882a593Smuzhiyun struct qla2300_fw_dump *fw;
735*4882a593Smuzhiyun void *nxt;
736*4882a593Smuzhiyun struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
737*4882a593Smuzhiyun
738*4882a593Smuzhiyun lockdep_assert_held(&ha->hardware_lock);
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun if (!ha->fw_dump) {
741*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd002,
742*4882a593Smuzhiyun "No buffer available for dump.\n");
743*4882a593Smuzhiyun return;
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun if (ha->fw_dumped) {
747*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd003,
748*4882a593Smuzhiyun "Firmware has been previously dumped (%p) "
749*4882a593Smuzhiyun "-- ignoring request.\n",
750*4882a593Smuzhiyun ha->fw_dump);
751*4882a593Smuzhiyun return;
752*4882a593Smuzhiyun }
753*4882a593Smuzhiyun fw = &ha->fw_dump->isp.isp23;
754*4882a593Smuzhiyun qla2xxx_prep_dump(ha, ha->fw_dump);
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun rval = QLA_SUCCESS;
757*4882a593Smuzhiyun fw->hccr = htons(rd_reg_word(®->hccr));
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun /* Pause RISC. */
760*4882a593Smuzhiyun wrt_reg_word(®->hccr, HCCR_PAUSE_RISC);
761*4882a593Smuzhiyun if (IS_QLA2300(ha)) {
762*4882a593Smuzhiyun for (cnt = 30000;
763*4882a593Smuzhiyun (rd_reg_word(®->hccr) & HCCR_RISC_PAUSE) == 0 &&
764*4882a593Smuzhiyun rval == QLA_SUCCESS; cnt--) {
765*4882a593Smuzhiyun if (cnt)
766*4882a593Smuzhiyun udelay(100);
767*4882a593Smuzhiyun else
768*4882a593Smuzhiyun rval = QLA_FUNCTION_TIMEOUT;
769*4882a593Smuzhiyun }
770*4882a593Smuzhiyun } else {
771*4882a593Smuzhiyun rd_reg_word(®->hccr); /* PCI Posting. */
772*4882a593Smuzhiyun udelay(10);
773*4882a593Smuzhiyun }
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun if (rval == QLA_SUCCESS) {
776*4882a593Smuzhiyun dmp_reg = ®->flash_address;
777*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->pbiu_reg); cnt++, dmp_reg++)
778*4882a593Smuzhiyun fw->pbiu_reg[cnt] = htons(rd_reg_word(dmp_reg));
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun dmp_reg = ®->u.isp2300.req_q_in;
781*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_host_reg);
782*4882a593Smuzhiyun cnt++, dmp_reg++)
783*4882a593Smuzhiyun fw->risc_host_reg[cnt] = htons(rd_reg_word(dmp_reg));
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun dmp_reg = ®->u.isp2300.mailbox0;
786*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg);
787*4882a593Smuzhiyun cnt++, dmp_reg++)
788*4882a593Smuzhiyun fw->mailbox_reg[cnt] = htons(rd_reg_word(dmp_reg));
789*4882a593Smuzhiyun
790*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, 0x40);
791*4882a593Smuzhiyun qla2xxx_read_window(reg, 32, fw->resp_dma_reg);
792*4882a593Smuzhiyun
793*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, 0x50);
794*4882a593Smuzhiyun qla2xxx_read_window(reg, 48, fw->dma_reg);
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, 0x00);
797*4882a593Smuzhiyun dmp_reg = ®->risc_hw;
798*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_hdw_reg);
799*4882a593Smuzhiyun cnt++, dmp_reg++)
800*4882a593Smuzhiyun fw->risc_hdw_reg[cnt] = htons(rd_reg_word(dmp_reg));
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2000);
803*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2200);
806*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2400);
809*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);
810*4882a593Smuzhiyun
811*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2600);
812*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);
813*4882a593Smuzhiyun
814*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2800);
815*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);
816*4882a593Smuzhiyun
817*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2A00);
818*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2C00);
821*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);
822*4882a593Smuzhiyun
823*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2E00);
824*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);
825*4882a593Smuzhiyun
826*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, 0x10);
827*4882a593Smuzhiyun qla2xxx_read_window(reg, 64, fw->frame_buf_hdw_reg);
828*4882a593Smuzhiyun
829*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, 0x20);
830*4882a593Smuzhiyun qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, 0x30);
833*4882a593Smuzhiyun qla2xxx_read_window(reg, 64, fw->fpm_b1_reg);
834*4882a593Smuzhiyun
835*4882a593Smuzhiyun /* Reset RISC. */
836*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, CSR_ISP_SOFT_RESET);
837*4882a593Smuzhiyun for (cnt = 0; cnt < 30000; cnt++) {
838*4882a593Smuzhiyun if ((rd_reg_word(®->ctrl_status) &
839*4882a593Smuzhiyun CSR_ISP_SOFT_RESET) == 0)
840*4882a593Smuzhiyun break;
841*4882a593Smuzhiyun
842*4882a593Smuzhiyun udelay(10);
843*4882a593Smuzhiyun }
844*4882a593Smuzhiyun }
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun if (!IS_QLA2300(ha)) {
847*4882a593Smuzhiyun for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
848*4882a593Smuzhiyun rval == QLA_SUCCESS; cnt--) {
849*4882a593Smuzhiyun if (cnt)
850*4882a593Smuzhiyun udelay(100);
851*4882a593Smuzhiyun else
852*4882a593Smuzhiyun rval = QLA_FUNCTION_TIMEOUT;
853*4882a593Smuzhiyun }
854*4882a593Smuzhiyun }
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun /* Get RISC SRAM. */
857*4882a593Smuzhiyun if (rval == QLA_SUCCESS)
858*4882a593Smuzhiyun rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram,
859*4882a593Smuzhiyun ARRAY_SIZE(fw->risc_ram), &nxt);
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun /* Get stack SRAM. */
862*4882a593Smuzhiyun if (rval == QLA_SUCCESS)
863*4882a593Smuzhiyun rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram,
864*4882a593Smuzhiyun ARRAY_SIZE(fw->stack_ram), &nxt);
865*4882a593Smuzhiyun
866*4882a593Smuzhiyun /* Get data SRAM. */
867*4882a593Smuzhiyun if (rval == QLA_SUCCESS)
868*4882a593Smuzhiyun rval = qla2xxx_dump_ram(ha, 0x11000, fw->data_ram,
869*4882a593Smuzhiyun ha->fw_memory_size - 0x11000 + 1, &nxt);
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun if (rval == QLA_SUCCESS)
872*4882a593Smuzhiyun qla2xxx_copy_queues(ha, nxt);
873*4882a593Smuzhiyun
874*4882a593Smuzhiyun qla2xxx_dump_post_process(base_vha, rval);
875*4882a593Smuzhiyun }
876*4882a593Smuzhiyun
877*4882a593Smuzhiyun /**
878*4882a593Smuzhiyun * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware.
879*4882a593Smuzhiyun * @vha: HA context
880*4882a593Smuzhiyun */
881*4882a593Smuzhiyun void
qla2100_fw_dump(scsi_qla_host_t * vha)882*4882a593Smuzhiyun qla2100_fw_dump(scsi_qla_host_t *vha)
883*4882a593Smuzhiyun {
884*4882a593Smuzhiyun int rval;
885*4882a593Smuzhiyun uint32_t cnt, timer;
886*4882a593Smuzhiyun uint16_t risc_address = 0;
887*4882a593Smuzhiyun uint16_t mb0 = 0, mb2 = 0;
888*4882a593Smuzhiyun struct qla_hw_data *ha = vha->hw;
889*4882a593Smuzhiyun struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
890*4882a593Smuzhiyun __le16 __iomem *dmp_reg;
891*4882a593Smuzhiyun struct qla2100_fw_dump *fw;
892*4882a593Smuzhiyun struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
893*4882a593Smuzhiyun
894*4882a593Smuzhiyun lockdep_assert_held(&ha->hardware_lock);
895*4882a593Smuzhiyun
896*4882a593Smuzhiyun if (!ha->fw_dump) {
897*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd004,
898*4882a593Smuzhiyun "No buffer available for dump.\n");
899*4882a593Smuzhiyun return;
900*4882a593Smuzhiyun }
901*4882a593Smuzhiyun
902*4882a593Smuzhiyun if (ha->fw_dumped) {
903*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd005,
904*4882a593Smuzhiyun "Firmware has been previously dumped (%p) "
905*4882a593Smuzhiyun "-- ignoring request.\n",
906*4882a593Smuzhiyun ha->fw_dump);
907*4882a593Smuzhiyun return;
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun fw = &ha->fw_dump->isp.isp21;
910*4882a593Smuzhiyun qla2xxx_prep_dump(ha, ha->fw_dump);
911*4882a593Smuzhiyun
912*4882a593Smuzhiyun rval = QLA_SUCCESS;
913*4882a593Smuzhiyun fw->hccr = htons(rd_reg_word(®->hccr));
914*4882a593Smuzhiyun
915*4882a593Smuzhiyun /* Pause RISC. */
916*4882a593Smuzhiyun wrt_reg_word(®->hccr, HCCR_PAUSE_RISC);
917*4882a593Smuzhiyun for (cnt = 30000; (rd_reg_word(®->hccr) & HCCR_RISC_PAUSE) == 0 &&
918*4882a593Smuzhiyun rval == QLA_SUCCESS; cnt--) {
919*4882a593Smuzhiyun if (cnt)
920*4882a593Smuzhiyun udelay(100);
921*4882a593Smuzhiyun else
922*4882a593Smuzhiyun rval = QLA_FUNCTION_TIMEOUT;
923*4882a593Smuzhiyun }
924*4882a593Smuzhiyun if (rval == QLA_SUCCESS) {
925*4882a593Smuzhiyun dmp_reg = ®->flash_address;
926*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->pbiu_reg); cnt++, dmp_reg++)
927*4882a593Smuzhiyun fw->pbiu_reg[cnt] = htons(rd_reg_word(dmp_reg));
928*4882a593Smuzhiyun
929*4882a593Smuzhiyun dmp_reg = ®->u.isp2100.mailbox0;
930*4882a593Smuzhiyun for (cnt = 0; cnt < ha->mbx_count; cnt++, dmp_reg++) {
931*4882a593Smuzhiyun if (cnt == 8)
932*4882a593Smuzhiyun dmp_reg = ®->u_end.isp2200.mailbox8;
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun fw->mailbox_reg[cnt] = htons(rd_reg_word(dmp_reg));
935*4882a593Smuzhiyun }
936*4882a593Smuzhiyun
937*4882a593Smuzhiyun dmp_reg = ®->u.isp2100.unused_2[0];
938*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->dma_reg); cnt++, dmp_reg++)
939*4882a593Smuzhiyun fw->dma_reg[cnt] = htons(rd_reg_word(dmp_reg));
940*4882a593Smuzhiyun
941*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, 0x00);
942*4882a593Smuzhiyun dmp_reg = ®->risc_hw;
943*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_hdw_reg); cnt++, dmp_reg++)
944*4882a593Smuzhiyun fw->risc_hdw_reg[cnt] = htons(rd_reg_word(dmp_reg));
945*4882a593Smuzhiyun
946*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2000);
947*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);
948*4882a593Smuzhiyun
949*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2100);
950*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);
951*4882a593Smuzhiyun
952*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2200);
953*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);
954*4882a593Smuzhiyun
955*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2300);
956*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);
957*4882a593Smuzhiyun
958*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2400);
959*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2500);
962*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);
963*4882a593Smuzhiyun
964*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2600);
965*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);
966*4882a593Smuzhiyun
967*4882a593Smuzhiyun wrt_reg_word(®->pcr, 0x2700);
968*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);
969*4882a593Smuzhiyun
970*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, 0x10);
971*4882a593Smuzhiyun qla2xxx_read_window(reg, 16, fw->frame_buf_hdw_reg);
972*4882a593Smuzhiyun
973*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, 0x20);
974*4882a593Smuzhiyun qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, 0x30);
977*4882a593Smuzhiyun qla2xxx_read_window(reg, 64, fw->fpm_b1_reg);
978*4882a593Smuzhiyun
979*4882a593Smuzhiyun /* Reset the ISP. */
980*4882a593Smuzhiyun wrt_reg_word(®->ctrl_status, CSR_ISP_SOFT_RESET);
981*4882a593Smuzhiyun }
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
984*4882a593Smuzhiyun rval == QLA_SUCCESS; cnt--) {
985*4882a593Smuzhiyun if (cnt)
986*4882a593Smuzhiyun udelay(100);
987*4882a593Smuzhiyun else
988*4882a593Smuzhiyun rval = QLA_FUNCTION_TIMEOUT;
989*4882a593Smuzhiyun }
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun /* Pause RISC. */
992*4882a593Smuzhiyun if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) &&
993*4882a593Smuzhiyun (rd_reg_word(®->mctr) & (BIT_1 | BIT_0)) != 0))) {
994*4882a593Smuzhiyun
995*4882a593Smuzhiyun wrt_reg_word(®->hccr, HCCR_PAUSE_RISC);
996*4882a593Smuzhiyun for (cnt = 30000;
997*4882a593Smuzhiyun (rd_reg_word(®->hccr) & HCCR_RISC_PAUSE) == 0 &&
998*4882a593Smuzhiyun rval == QLA_SUCCESS; cnt--) {
999*4882a593Smuzhiyun if (cnt)
1000*4882a593Smuzhiyun udelay(100);
1001*4882a593Smuzhiyun else
1002*4882a593Smuzhiyun rval = QLA_FUNCTION_TIMEOUT;
1003*4882a593Smuzhiyun }
1004*4882a593Smuzhiyun if (rval == QLA_SUCCESS) {
1005*4882a593Smuzhiyun /* Set memory configuration and timing. */
1006*4882a593Smuzhiyun if (IS_QLA2100(ha))
1007*4882a593Smuzhiyun wrt_reg_word(®->mctr, 0xf1);
1008*4882a593Smuzhiyun else
1009*4882a593Smuzhiyun wrt_reg_word(®->mctr, 0xf2);
1010*4882a593Smuzhiyun rd_reg_word(®->mctr); /* PCI Posting. */
1011*4882a593Smuzhiyun
1012*4882a593Smuzhiyun /* Release RISC. */
1013*4882a593Smuzhiyun wrt_reg_word(®->hccr, HCCR_RELEASE_RISC);
1014*4882a593Smuzhiyun }
1015*4882a593Smuzhiyun }
1016*4882a593Smuzhiyun
1017*4882a593Smuzhiyun if (rval == QLA_SUCCESS) {
1018*4882a593Smuzhiyun /* Get RISC SRAM. */
1019*4882a593Smuzhiyun risc_address = 0x1000;
1020*4882a593Smuzhiyun WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
1021*4882a593Smuzhiyun clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1022*4882a593Smuzhiyun }
1023*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_ram) && rval == QLA_SUCCESS;
1024*4882a593Smuzhiyun cnt++, risc_address++) {
1025*4882a593Smuzhiyun WRT_MAILBOX_REG(ha, reg, 1, risc_address);
1026*4882a593Smuzhiyun wrt_reg_word(®->hccr, HCCR_SET_HOST_INT);
1027*4882a593Smuzhiyun
1028*4882a593Smuzhiyun for (timer = 6000000; timer != 0; timer--) {
1029*4882a593Smuzhiyun /* Check for pending interrupts. */
1030*4882a593Smuzhiyun if (rd_reg_word(®->istatus) & ISR_RISC_INT) {
1031*4882a593Smuzhiyun if (rd_reg_word(®->semaphore) & BIT_0) {
1032*4882a593Smuzhiyun set_bit(MBX_INTERRUPT,
1033*4882a593Smuzhiyun &ha->mbx_cmd_flags);
1034*4882a593Smuzhiyun
1035*4882a593Smuzhiyun mb0 = RD_MAILBOX_REG(ha, reg, 0);
1036*4882a593Smuzhiyun mb2 = RD_MAILBOX_REG(ha, reg, 2);
1037*4882a593Smuzhiyun
1038*4882a593Smuzhiyun wrt_reg_word(®->semaphore, 0);
1039*4882a593Smuzhiyun wrt_reg_word(®->hccr,
1040*4882a593Smuzhiyun HCCR_CLR_RISC_INT);
1041*4882a593Smuzhiyun rd_reg_word(®->hccr);
1042*4882a593Smuzhiyun break;
1043*4882a593Smuzhiyun }
1044*4882a593Smuzhiyun wrt_reg_word(®->hccr, HCCR_CLR_RISC_INT);
1045*4882a593Smuzhiyun rd_reg_word(®->hccr);
1046*4882a593Smuzhiyun }
1047*4882a593Smuzhiyun udelay(5);
1048*4882a593Smuzhiyun }
1049*4882a593Smuzhiyun
1050*4882a593Smuzhiyun if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
1051*4882a593Smuzhiyun rval = mb0 & MBS_MASK;
1052*4882a593Smuzhiyun fw->risc_ram[cnt] = htons(mb2);
1053*4882a593Smuzhiyun } else {
1054*4882a593Smuzhiyun rval = QLA_FUNCTION_FAILED;
1055*4882a593Smuzhiyun }
1056*4882a593Smuzhiyun }
1057*4882a593Smuzhiyun
1058*4882a593Smuzhiyun if (rval == QLA_SUCCESS)
1059*4882a593Smuzhiyun qla2xxx_copy_queues(ha, &fw->queue_dump[0]);
1060*4882a593Smuzhiyun
1061*4882a593Smuzhiyun qla2xxx_dump_post_process(base_vha, rval);
1062*4882a593Smuzhiyun }
1063*4882a593Smuzhiyun
1064*4882a593Smuzhiyun void
qla24xx_fw_dump(scsi_qla_host_t * vha)1065*4882a593Smuzhiyun qla24xx_fw_dump(scsi_qla_host_t *vha)
1066*4882a593Smuzhiyun {
1067*4882a593Smuzhiyun int rval;
1068*4882a593Smuzhiyun uint32_t cnt;
1069*4882a593Smuzhiyun struct qla_hw_data *ha = vha->hw;
1070*4882a593Smuzhiyun struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1071*4882a593Smuzhiyun __le32 __iomem *dmp_reg;
1072*4882a593Smuzhiyun __be32 *iter_reg;
1073*4882a593Smuzhiyun __le16 __iomem *mbx_reg;
1074*4882a593Smuzhiyun struct qla24xx_fw_dump *fw;
1075*4882a593Smuzhiyun void *nxt;
1076*4882a593Smuzhiyun void *nxt_chain;
1077*4882a593Smuzhiyun __be32 *last_chain = NULL;
1078*4882a593Smuzhiyun struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
1079*4882a593Smuzhiyun
1080*4882a593Smuzhiyun lockdep_assert_held(&ha->hardware_lock);
1081*4882a593Smuzhiyun
1082*4882a593Smuzhiyun if (IS_P3P_TYPE(ha))
1083*4882a593Smuzhiyun return;
1084*4882a593Smuzhiyun
1085*4882a593Smuzhiyun ha->fw_dump_cap_flags = 0;
1086*4882a593Smuzhiyun
1087*4882a593Smuzhiyun if (!ha->fw_dump) {
1088*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd006,
1089*4882a593Smuzhiyun "No buffer available for dump.\n");
1090*4882a593Smuzhiyun return;
1091*4882a593Smuzhiyun }
1092*4882a593Smuzhiyun
1093*4882a593Smuzhiyun if (ha->fw_dumped) {
1094*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd007,
1095*4882a593Smuzhiyun "Firmware has been previously dumped (%p) "
1096*4882a593Smuzhiyun "-- ignoring request.\n",
1097*4882a593Smuzhiyun ha->fw_dump);
1098*4882a593Smuzhiyun return;
1099*4882a593Smuzhiyun }
1100*4882a593Smuzhiyun QLA_FW_STOPPED(ha);
1101*4882a593Smuzhiyun fw = &ha->fw_dump->isp.isp24;
1102*4882a593Smuzhiyun qla2xxx_prep_dump(ha, ha->fw_dump);
1103*4882a593Smuzhiyun
1104*4882a593Smuzhiyun fw->host_status = htonl(rd_reg_dword(®->host_status));
1105*4882a593Smuzhiyun
1106*4882a593Smuzhiyun /*
1107*4882a593Smuzhiyun * Pause RISC. No need to track timeout, as resetting the chip
1108*4882a593Smuzhiyun * is the right approach incase of pause timeout
1109*4882a593Smuzhiyun */
1110*4882a593Smuzhiyun qla24xx_pause_risc(reg, ha);
1111*4882a593Smuzhiyun
1112*4882a593Smuzhiyun /* Host interface registers. */
1113*4882a593Smuzhiyun dmp_reg = ®->flash_addr;
1114*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
1115*4882a593Smuzhiyun fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg));
1116*4882a593Smuzhiyun
1117*4882a593Smuzhiyun /* Disable interrupts. */
1118*4882a593Smuzhiyun wrt_reg_dword(®->ictrl, 0);
1119*4882a593Smuzhiyun rd_reg_dword(®->ictrl);
1120*4882a593Smuzhiyun
1121*4882a593Smuzhiyun /* Shadow registers. */
1122*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x0F70);
1123*4882a593Smuzhiyun rd_reg_dword(®->iobase_addr);
1124*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0000000);
1125*4882a593Smuzhiyun fw->shadow_reg[0] = htonl(rd_reg_dword(®->iobase_sdata));
1126*4882a593Smuzhiyun
1127*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0100000);
1128*4882a593Smuzhiyun fw->shadow_reg[1] = htonl(rd_reg_dword(®->iobase_sdata));
1129*4882a593Smuzhiyun
1130*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0200000);
1131*4882a593Smuzhiyun fw->shadow_reg[2] = htonl(rd_reg_dword(®->iobase_sdata));
1132*4882a593Smuzhiyun
1133*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0300000);
1134*4882a593Smuzhiyun fw->shadow_reg[3] = htonl(rd_reg_dword(®->iobase_sdata));
1135*4882a593Smuzhiyun
1136*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0400000);
1137*4882a593Smuzhiyun fw->shadow_reg[4] = htonl(rd_reg_dword(®->iobase_sdata));
1138*4882a593Smuzhiyun
1139*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0500000);
1140*4882a593Smuzhiyun fw->shadow_reg[5] = htonl(rd_reg_dword(®->iobase_sdata));
1141*4882a593Smuzhiyun
1142*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0600000);
1143*4882a593Smuzhiyun fw->shadow_reg[6] = htonl(rd_reg_dword(®->iobase_sdata));
1144*4882a593Smuzhiyun
1145*4882a593Smuzhiyun /* Mailbox registers. */
1146*4882a593Smuzhiyun mbx_reg = ®->mailbox0;
1147*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
1148*4882a593Smuzhiyun fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg));
1149*4882a593Smuzhiyun
1150*4882a593Smuzhiyun /* Transfer sequence registers. */
1151*4882a593Smuzhiyun iter_reg = fw->xseq_gp_reg;
1152*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1153*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1154*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1155*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1156*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1157*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1158*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1159*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
1160*4882a593Smuzhiyun
1161*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBFE0, 16, fw->xseq_0_reg);
1162*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
1163*4882a593Smuzhiyun
1164*4882a593Smuzhiyun /* Receive sequence registers. */
1165*4882a593Smuzhiyun iter_reg = fw->rseq_gp_reg;
1166*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1167*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1168*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1169*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1170*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1171*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1172*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1173*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
1174*4882a593Smuzhiyun
1175*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFD0, 16, fw->rseq_0_reg);
1176*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1177*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
1178*4882a593Smuzhiyun
1179*4882a593Smuzhiyun /* Command DMA registers. */
1180*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
1181*4882a593Smuzhiyun
1182*4882a593Smuzhiyun /* Queues. */
1183*4882a593Smuzhiyun iter_reg = fw->req0_dma_reg;
1184*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1185*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
1186*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
1187*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
1188*4882a593Smuzhiyun
1189*4882a593Smuzhiyun iter_reg = fw->resp0_dma_reg;
1190*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1191*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
1192*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
1193*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
1194*4882a593Smuzhiyun
1195*4882a593Smuzhiyun iter_reg = fw->req1_dma_reg;
1196*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1197*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
1198*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
1199*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
1200*4882a593Smuzhiyun
1201*4882a593Smuzhiyun /* Transmit DMA registers. */
1202*4882a593Smuzhiyun iter_reg = fw->xmt0_dma_reg;
1203*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1204*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7610, 16, iter_reg);
1205*4882a593Smuzhiyun
1206*4882a593Smuzhiyun iter_reg = fw->xmt1_dma_reg;
1207*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1208*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7630, 16, iter_reg);
1209*4882a593Smuzhiyun
1210*4882a593Smuzhiyun iter_reg = fw->xmt2_dma_reg;
1211*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1212*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7650, 16, iter_reg);
1213*4882a593Smuzhiyun
1214*4882a593Smuzhiyun iter_reg = fw->xmt3_dma_reg;
1215*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1216*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7670, 16, iter_reg);
1217*4882a593Smuzhiyun
1218*4882a593Smuzhiyun iter_reg = fw->xmt4_dma_reg;
1219*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1220*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7690, 16, iter_reg);
1221*4882a593Smuzhiyun
1222*4882a593Smuzhiyun qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
1223*4882a593Smuzhiyun
1224*4882a593Smuzhiyun /* Receive DMA registers. */
1225*4882a593Smuzhiyun iter_reg = fw->rcvt0_data_dma_reg;
1226*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1227*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7710, 16, iter_reg);
1228*4882a593Smuzhiyun
1229*4882a593Smuzhiyun iter_reg = fw->rcvt1_data_dma_reg;
1230*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1231*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7730, 16, iter_reg);
1232*4882a593Smuzhiyun
1233*4882a593Smuzhiyun /* RISC registers. */
1234*4882a593Smuzhiyun iter_reg = fw->risc_gp_reg;
1235*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1236*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1237*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1238*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1239*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1240*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1241*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1242*4882a593Smuzhiyun qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
1243*4882a593Smuzhiyun
1244*4882a593Smuzhiyun /* Local memory controller registers. */
1245*4882a593Smuzhiyun iter_reg = fw->lmc_reg;
1246*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1247*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1248*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1249*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1250*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1251*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1252*4882a593Smuzhiyun qla24xx_read_window(reg, 0x3060, 16, iter_reg);
1253*4882a593Smuzhiyun
1254*4882a593Smuzhiyun /* Fibre Protocol Module registers. */
1255*4882a593Smuzhiyun iter_reg = fw->fpm_hdw_reg;
1256*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1257*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1258*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1259*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1260*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1261*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1262*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1263*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1264*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1265*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1266*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1267*4882a593Smuzhiyun qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
1268*4882a593Smuzhiyun
1269*4882a593Smuzhiyun /* Frame Buffer registers. */
1270*4882a593Smuzhiyun iter_reg = fw->fb_hdw_reg;
1271*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1272*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1273*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1274*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1275*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1276*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1277*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1278*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1279*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1280*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1281*4882a593Smuzhiyun qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
1282*4882a593Smuzhiyun
1283*4882a593Smuzhiyun rval = qla24xx_soft_reset(ha);
1284*4882a593Smuzhiyun if (rval != QLA_SUCCESS)
1285*4882a593Smuzhiyun goto qla24xx_fw_dump_failed_0;
1286*4882a593Smuzhiyun
1287*4882a593Smuzhiyun rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
1288*4882a593Smuzhiyun &nxt);
1289*4882a593Smuzhiyun if (rval != QLA_SUCCESS)
1290*4882a593Smuzhiyun goto qla24xx_fw_dump_failed_0;
1291*4882a593Smuzhiyun
1292*4882a593Smuzhiyun nxt = qla2xxx_copy_queues(ha, nxt);
1293*4882a593Smuzhiyun
1294*4882a593Smuzhiyun qla24xx_copy_eft(ha, nxt);
1295*4882a593Smuzhiyun
1296*4882a593Smuzhiyun nxt_chain = (void *)ha->fw_dump + ha->chain_offset;
1297*4882a593Smuzhiyun nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
1298*4882a593Smuzhiyun if (last_chain) {
1299*4882a593Smuzhiyun ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
1300*4882a593Smuzhiyun *last_chain |= htonl(DUMP_CHAIN_LAST);
1301*4882a593Smuzhiyun }
1302*4882a593Smuzhiyun
1303*4882a593Smuzhiyun /* Adjust valid length. */
1304*4882a593Smuzhiyun ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1305*4882a593Smuzhiyun
1306*4882a593Smuzhiyun qla24xx_fw_dump_failed_0:
1307*4882a593Smuzhiyun qla2xxx_dump_post_process(base_vha, rval);
1308*4882a593Smuzhiyun }
1309*4882a593Smuzhiyun
1310*4882a593Smuzhiyun void
qla25xx_fw_dump(scsi_qla_host_t * vha)1311*4882a593Smuzhiyun qla25xx_fw_dump(scsi_qla_host_t *vha)
1312*4882a593Smuzhiyun {
1313*4882a593Smuzhiyun int rval;
1314*4882a593Smuzhiyun uint32_t cnt;
1315*4882a593Smuzhiyun struct qla_hw_data *ha = vha->hw;
1316*4882a593Smuzhiyun struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1317*4882a593Smuzhiyun __le32 __iomem *dmp_reg;
1318*4882a593Smuzhiyun __be32 *iter_reg;
1319*4882a593Smuzhiyun __le16 __iomem *mbx_reg;
1320*4882a593Smuzhiyun struct qla25xx_fw_dump *fw;
1321*4882a593Smuzhiyun void *nxt, *nxt_chain;
1322*4882a593Smuzhiyun __be32 *last_chain = NULL;
1323*4882a593Smuzhiyun struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
1324*4882a593Smuzhiyun
1325*4882a593Smuzhiyun lockdep_assert_held(&ha->hardware_lock);
1326*4882a593Smuzhiyun
1327*4882a593Smuzhiyun ha->fw_dump_cap_flags = 0;
1328*4882a593Smuzhiyun
1329*4882a593Smuzhiyun if (!ha->fw_dump) {
1330*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd008,
1331*4882a593Smuzhiyun "No buffer available for dump.\n");
1332*4882a593Smuzhiyun return;
1333*4882a593Smuzhiyun }
1334*4882a593Smuzhiyun
1335*4882a593Smuzhiyun if (ha->fw_dumped) {
1336*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd009,
1337*4882a593Smuzhiyun "Firmware has been previously dumped (%p) "
1338*4882a593Smuzhiyun "-- ignoring request.\n",
1339*4882a593Smuzhiyun ha->fw_dump);
1340*4882a593Smuzhiyun return;
1341*4882a593Smuzhiyun }
1342*4882a593Smuzhiyun QLA_FW_STOPPED(ha);
1343*4882a593Smuzhiyun fw = &ha->fw_dump->isp.isp25;
1344*4882a593Smuzhiyun qla2xxx_prep_dump(ha, ha->fw_dump);
1345*4882a593Smuzhiyun ha->fw_dump->version = htonl(2);
1346*4882a593Smuzhiyun
1347*4882a593Smuzhiyun fw->host_status = htonl(rd_reg_dword(®->host_status));
1348*4882a593Smuzhiyun
1349*4882a593Smuzhiyun /*
1350*4882a593Smuzhiyun * Pause RISC. No need to track timeout, as resetting the chip
1351*4882a593Smuzhiyun * is the right approach incase of pause timeout
1352*4882a593Smuzhiyun */
1353*4882a593Smuzhiyun qla24xx_pause_risc(reg, ha);
1354*4882a593Smuzhiyun
1355*4882a593Smuzhiyun /* Host/Risc registers. */
1356*4882a593Smuzhiyun iter_reg = fw->host_risc_reg;
1357*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
1358*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7010, 16, iter_reg);
1359*4882a593Smuzhiyun
1360*4882a593Smuzhiyun /* PCIe registers. */
1361*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x7C00);
1362*4882a593Smuzhiyun rd_reg_dword(®->iobase_addr);
1363*4882a593Smuzhiyun wrt_reg_dword(®->iobase_window, 0x01);
1364*4882a593Smuzhiyun dmp_reg = ®->iobase_c4;
1365*4882a593Smuzhiyun fw->pcie_regs[0] = htonl(rd_reg_dword(dmp_reg));
1366*4882a593Smuzhiyun dmp_reg++;
1367*4882a593Smuzhiyun fw->pcie_regs[1] = htonl(rd_reg_dword(dmp_reg));
1368*4882a593Smuzhiyun dmp_reg++;
1369*4882a593Smuzhiyun fw->pcie_regs[2] = htonl(rd_reg_dword(dmp_reg));
1370*4882a593Smuzhiyun fw->pcie_regs[3] = htonl(rd_reg_dword(®->iobase_window));
1371*4882a593Smuzhiyun
1372*4882a593Smuzhiyun wrt_reg_dword(®->iobase_window, 0x00);
1373*4882a593Smuzhiyun rd_reg_dword(®->iobase_window);
1374*4882a593Smuzhiyun
1375*4882a593Smuzhiyun /* Host interface registers. */
1376*4882a593Smuzhiyun dmp_reg = ®->flash_addr;
1377*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
1378*4882a593Smuzhiyun fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg));
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun /* Disable interrupts. */
1381*4882a593Smuzhiyun wrt_reg_dword(®->ictrl, 0);
1382*4882a593Smuzhiyun rd_reg_dword(®->ictrl);
1383*4882a593Smuzhiyun
1384*4882a593Smuzhiyun /* Shadow registers. */
1385*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x0F70);
1386*4882a593Smuzhiyun rd_reg_dword(®->iobase_addr);
1387*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0000000);
1388*4882a593Smuzhiyun fw->shadow_reg[0] = htonl(rd_reg_dword(®->iobase_sdata));
1389*4882a593Smuzhiyun
1390*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0100000);
1391*4882a593Smuzhiyun fw->shadow_reg[1] = htonl(rd_reg_dword(®->iobase_sdata));
1392*4882a593Smuzhiyun
1393*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0200000);
1394*4882a593Smuzhiyun fw->shadow_reg[2] = htonl(rd_reg_dword(®->iobase_sdata));
1395*4882a593Smuzhiyun
1396*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0300000);
1397*4882a593Smuzhiyun fw->shadow_reg[3] = htonl(rd_reg_dword(®->iobase_sdata));
1398*4882a593Smuzhiyun
1399*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0400000);
1400*4882a593Smuzhiyun fw->shadow_reg[4] = htonl(rd_reg_dword(®->iobase_sdata));
1401*4882a593Smuzhiyun
1402*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0500000);
1403*4882a593Smuzhiyun fw->shadow_reg[5] = htonl(rd_reg_dword(®->iobase_sdata));
1404*4882a593Smuzhiyun
1405*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0600000);
1406*4882a593Smuzhiyun fw->shadow_reg[6] = htonl(rd_reg_dword(®->iobase_sdata));
1407*4882a593Smuzhiyun
1408*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0700000);
1409*4882a593Smuzhiyun fw->shadow_reg[7] = htonl(rd_reg_dword(®->iobase_sdata));
1410*4882a593Smuzhiyun
1411*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0800000);
1412*4882a593Smuzhiyun fw->shadow_reg[8] = htonl(rd_reg_dword(®->iobase_sdata));
1413*4882a593Smuzhiyun
1414*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0900000);
1415*4882a593Smuzhiyun fw->shadow_reg[9] = htonl(rd_reg_dword(®->iobase_sdata));
1416*4882a593Smuzhiyun
1417*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0A00000);
1418*4882a593Smuzhiyun fw->shadow_reg[10] = htonl(rd_reg_dword(®->iobase_sdata));
1419*4882a593Smuzhiyun
1420*4882a593Smuzhiyun /* RISC I/O register. */
1421*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x0010);
1422*4882a593Smuzhiyun fw->risc_io_reg = htonl(rd_reg_dword(®->iobase_window));
1423*4882a593Smuzhiyun
1424*4882a593Smuzhiyun /* Mailbox registers. */
1425*4882a593Smuzhiyun mbx_reg = ®->mailbox0;
1426*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
1427*4882a593Smuzhiyun fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg));
1428*4882a593Smuzhiyun
1429*4882a593Smuzhiyun /* Transfer sequence registers. */
1430*4882a593Smuzhiyun iter_reg = fw->xseq_gp_reg;
1431*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1432*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1433*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1434*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1435*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1436*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1437*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1438*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
1439*4882a593Smuzhiyun
1440*4882a593Smuzhiyun iter_reg = fw->xseq_0_reg;
1441*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
1442*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
1443*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
1444*4882a593Smuzhiyun
1445*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
1446*4882a593Smuzhiyun
1447*4882a593Smuzhiyun /* Receive sequence registers. */
1448*4882a593Smuzhiyun iter_reg = fw->rseq_gp_reg;
1449*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1450*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1451*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1452*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1453*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1454*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1455*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1456*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
1457*4882a593Smuzhiyun
1458*4882a593Smuzhiyun iter_reg = fw->rseq_0_reg;
1459*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
1460*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
1461*4882a593Smuzhiyun
1462*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1463*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
1464*4882a593Smuzhiyun
1465*4882a593Smuzhiyun /* Auxiliary sequence registers. */
1466*4882a593Smuzhiyun iter_reg = fw->aseq_gp_reg;
1467*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
1468*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
1469*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
1470*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
1471*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
1472*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
1473*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
1474*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB070, 16, iter_reg);
1475*4882a593Smuzhiyun
1476*4882a593Smuzhiyun iter_reg = fw->aseq_0_reg;
1477*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
1478*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
1479*4882a593Smuzhiyun
1480*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
1481*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
1482*4882a593Smuzhiyun
1483*4882a593Smuzhiyun /* Command DMA registers. */
1484*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
1485*4882a593Smuzhiyun
1486*4882a593Smuzhiyun /* Queues. */
1487*4882a593Smuzhiyun iter_reg = fw->req0_dma_reg;
1488*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1489*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
1490*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
1491*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
1492*4882a593Smuzhiyun
1493*4882a593Smuzhiyun iter_reg = fw->resp0_dma_reg;
1494*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1495*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
1496*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
1497*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
1498*4882a593Smuzhiyun
1499*4882a593Smuzhiyun iter_reg = fw->req1_dma_reg;
1500*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1501*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
1502*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
1503*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
1504*4882a593Smuzhiyun
1505*4882a593Smuzhiyun /* Transmit DMA registers. */
1506*4882a593Smuzhiyun iter_reg = fw->xmt0_dma_reg;
1507*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1508*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7610, 16, iter_reg);
1509*4882a593Smuzhiyun
1510*4882a593Smuzhiyun iter_reg = fw->xmt1_dma_reg;
1511*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1512*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7630, 16, iter_reg);
1513*4882a593Smuzhiyun
1514*4882a593Smuzhiyun iter_reg = fw->xmt2_dma_reg;
1515*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1516*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7650, 16, iter_reg);
1517*4882a593Smuzhiyun
1518*4882a593Smuzhiyun iter_reg = fw->xmt3_dma_reg;
1519*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1520*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7670, 16, iter_reg);
1521*4882a593Smuzhiyun
1522*4882a593Smuzhiyun iter_reg = fw->xmt4_dma_reg;
1523*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1524*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7690, 16, iter_reg);
1525*4882a593Smuzhiyun
1526*4882a593Smuzhiyun qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
1527*4882a593Smuzhiyun
1528*4882a593Smuzhiyun /* Receive DMA registers. */
1529*4882a593Smuzhiyun iter_reg = fw->rcvt0_data_dma_reg;
1530*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1531*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7710, 16, iter_reg);
1532*4882a593Smuzhiyun
1533*4882a593Smuzhiyun iter_reg = fw->rcvt1_data_dma_reg;
1534*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1535*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7730, 16, iter_reg);
1536*4882a593Smuzhiyun
1537*4882a593Smuzhiyun /* RISC registers. */
1538*4882a593Smuzhiyun iter_reg = fw->risc_gp_reg;
1539*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1540*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1541*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1542*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1543*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1544*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1545*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1546*4882a593Smuzhiyun qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
1547*4882a593Smuzhiyun
1548*4882a593Smuzhiyun /* Local memory controller registers. */
1549*4882a593Smuzhiyun iter_reg = fw->lmc_reg;
1550*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1551*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1552*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1553*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1554*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1555*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1556*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
1557*4882a593Smuzhiyun qla24xx_read_window(reg, 0x3070, 16, iter_reg);
1558*4882a593Smuzhiyun
1559*4882a593Smuzhiyun /* Fibre Protocol Module registers. */
1560*4882a593Smuzhiyun iter_reg = fw->fpm_hdw_reg;
1561*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1562*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1563*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1564*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1565*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1566*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1567*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1568*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1569*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1570*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1571*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1572*4882a593Smuzhiyun qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
1573*4882a593Smuzhiyun
1574*4882a593Smuzhiyun /* Frame Buffer registers. */
1575*4882a593Smuzhiyun iter_reg = fw->fb_hdw_reg;
1576*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1577*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1578*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1579*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1580*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1581*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1582*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1583*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1584*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1585*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1586*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
1587*4882a593Smuzhiyun qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
1588*4882a593Smuzhiyun
1589*4882a593Smuzhiyun /* Multi queue registers */
1590*4882a593Smuzhiyun nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
1591*4882a593Smuzhiyun &last_chain);
1592*4882a593Smuzhiyun
1593*4882a593Smuzhiyun rval = qla24xx_soft_reset(ha);
1594*4882a593Smuzhiyun if (rval != QLA_SUCCESS)
1595*4882a593Smuzhiyun goto qla25xx_fw_dump_failed_0;
1596*4882a593Smuzhiyun
1597*4882a593Smuzhiyun rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
1598*4882a593Smuzhiyun &nxt);
1599*4882a593Smuzhiyun if (rval != QLA_SUCCESS)
1600*4882a593Smuzhiyun goto qla25xx_fw_dump_failed_0;
1601*4882a593Smuzhiyun
1602*4882a593Smuzhiyun nxt = qla2xxx_copy_queues(ha, nxt);
1603*4882a593Smuzhiyun
1604*4882a593Smuzhiyun qla24xx_copy_eft(ha, nxt);
1605*4882a593Smuzhiyun
1606*4882a593Smuzhiyun /* Chain entries -- started with MQ. */
1607*4882a593Smuzhiyun nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
1608*4882a593Smuzhiyun nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
1609*4882a593Smuzhiyun nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
1610*4882a593Smuzhiyun nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, &last_chain);
1611*4882a593Smuzhiyun if (last_chain) {
1612*4882a593Smuzhiyun ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
1613*4882a593Smuzhiyun *last_chain |= htonl(DUMP_CHAIN_LAST);
1614*4882a593Smuzhiyun }
1615*4882a593Smuzhiyun
1616*4882a593Smuzhiyun /* Adjust valid length. */
1617*4882a593Smuzhiyun ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1618*4882a593Smuzhiyun
1619*4882a593Smuzhiyun qla25xx_fw_dump_failed_0:
1620*4882a593Smuzhiyun qla2xxx_dump_post_process(base_vha, rval);
1621*4882a593Smuzhiyun }
1622*4882a593Smuzhiyun
1623*4882a593Smuzhiyun void
qla81xx_fw_dump(scsi_qla_host_t * vha)1624*4882a593Smuzhiyun qla81xx_fw_dump(scsi_qla_host_t *vha)
1625*4882a593Smuzhiyun {
1626*4882a593Smuzhiyun int rval;
1627*4882a593Smuzhiyun uint32_t cnt;
1628*4882a593Smuzhiyun struct qla_hw_data *ha = vha->hw;
1629*4882a593Smuzhiyun struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1630*4882a593Smuzhiyun __le32 __iomem *dmp_reg;
1631*4882a593Smuzhiyun __be32 *iter_reg;
1632*4882a593Smuzhiyun __le16 __iomem *mbx_reg;
1633*4882a593Smuzhiyun struct qla81xx_fw_dump *fw;
1634*4882a593Smuzhiyun void *nxt, *nxt_chain;
1635*4882a593Smuzhiyun __be32 *last_chain = NULL;
1636*4882a593Smuzhiyun struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
1637*4882a593Smuzhiyun
1638*4882a593Smuzhiyun lockdep_assert_held(&ha->hardware_lock);
1639*4882a593Smuzhiyun
1640*4882a593Smuzhiyun ha->fw_dump_cap_flags = 0;
1641*4882a593Smuzhiyun
1642*4882a593Smuzhiyun if (!ha->fw_dump) {
1643*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd00a,
1644*4882a593Smuzhiyun "No buffer available for dump.\n");
1645*4882a593Smuzhiyun return;
1646*4882a593Smuzhiyun }
1647*4882a593Smuzhiyun
1648*4882a593Smuzhiyun if (ha->fw_dumped) {
1649*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd00b,
1650*4882a593Smuzhiyun "Firmware has been previously dumped (%p) "
1651*4882a593Smuzhiyun "-- ignoring request.\n",
1652*4882a593Smuzhiyun ha->fw_dump);
1653*4882a593Smuzhiyun return;
1654*4882a593Smuzhiyun }
1655*4882a593Smuzhiyun fw = &ha->fw_dump->isp.isp81;
1656*4882a593Smuzhiyun qla2xxx_prep_dump(ha, ha->fw_dump);
1657*4882a593Smuzhiyun
1658*4882a593Smuzhiyun fw->host_status = htonl(rd_reg_dword(®->host_status));
1659*4882a593Smuzhiyun
1660*4882a593Smuzhiyun /*
1661*4882a593Smuzhiyun * Pause RISC. No need to track timeout, as resetting the chip
1662*4882a593Smuzhiyun * is the right approach incase of pause timeout
1663*4882a593Smuzhiyun */
1664*4882a593Smuzhiyun qla24xx_pause_risc(reg, ha);
1665*4882a593Smuzhiyun
1666*4882a593Smuzhiyun /* Host/Risc registers. */
1667*4882a593Smuzhiyun iter_reg = fw->host_risc_reg;
1668*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
1669*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7010, 16, iter_reg);
1670*4882a593Smuzhiyun
1671*4882a593Smuzhiyun /* PCIe registers. */
1672*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x7C00);
1673*4882a593Smuzhiyun rd_reg_dword(®->iobase_addr);
1674*4882a593Smuzhiyun wrt_reg_dword(®->iobase_window, 0x01);
1675*4882a593Smuzhiyun dmp_reg = ®->iobase_c4;
1676*4882a593Smuzhiyun fw->pcie_regs[0] = htonl(rd_reg_dword(dmp_reg));
1677*4882a593Smuzhiyun dmp_reg++;
1678*4882a593Smuzhiyun fw->pcie_regs[1] = htonl(rd_reg_dword(dmp_reg));
1679*4882a593Smuzhiyun dmp_reg++;
1680*4882a593Smuzhiyun fw->pcie_regs[2] = htonl(rd_reg_dword(dmp_reg));
1681*4882a593Smuzhiyun fw->pcie_regs[3] = htonl(rd_reg_dword(®->iobase_window));
1682*4882a593Smuzhiyun
1683*4882a593Smuzhiyun wrt_reg_dword(®->iobase_window, 0x00);
1684*4882a593Smuzhiyun rd_reg_dword(®->iobase_window);
1685*4882a593Smuzhiyun
1686*4882a593Smuzhiyun /* Host interface registers. */
1687*4882a593Smuzhiyun dmp_reg = ®->flash_addr;
1688*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
1689*4882a593Smuzhiyun fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg));
1690*4882a593Smuzhiyun
1691*4882a593Smuzhiyun /* Disable interrupts. */
1692*4882a593Smuzhiyun wrt_reg_dword(®->ictrl, 0);
1693*4882a593Smuzhiyun rd_reg_dword(®->ictrl);
1694*4882a593Smuzhiyun
1695*4882a593Smuzhiyun /* Shadow registers. */
1696*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x0F70);
1697*4882a593Smuzhiyun rd_reg_dword(®->iobase_addr);
1698*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0000000);
1699*4882a593Smuzhiyun fw->shadow_reg[0] = htonl(rd_reg_dword(®->iobase_sdata));
1700*4882a593Smuzhiyun
1701*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0100000);
1702*4882a593Smuzhiyun fw->shadow_reg[1] = htonl(rd_reg_dword(®->iobase_sdata));
1703*4882a593Smuzhiyun
1704*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0200000);
1705*4882a593Smuzhiyun fw->shadow_reg[2] = htonl(rd_reg_dword(®->iobase_sdata));
1706*4882a593Smuzhiyun
1707*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0300000);
1708*4882a593Smuzhiyun fw->shadow_reg[3] = htonl(rd_reg_dword(®->iobase_sdata));
1709*4882a593Smuzhiyun
1710*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0400000);
1711*4882a593Smuzhiyun fw->shadow_reg[4] = htonl(rd_reg_dword(®->iobase_sdata));
1712*4882a593Smuzhiyun
1713*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0500000);
1714*4882a593Smuzhiyun fw->shadow_reg[5] = htonl(rd_reg_dword(®->iobase_sdata));
1715*4882a593Smuzhiyun
1716*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0600000);
1717*4882a593Smuzhiyun fw->shadow_reg[6] = htonl(rd_reg_dword(®->iobase_sdata));
1718*4882a593Smuzhiyun
1719*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0700000);
1720*4882a593Smuzhiyun fw->shadow_reg[7] = htonl(rd_reg_dword(®->iobase_sdata));
1721*4882a593Smuzhiyun
1722*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0800000);
1723*4882a593Smuzhiyun fw->shadow_reg[8] = htonl(rd_reg_dword(®->iobase_sdata));
1724*4882a593Smuzhiyun
1725*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0900000);
1726*4882a593Smuzhiyun fw->shadow_reg[9] = htonl(rd_reg_dword(®->iobase_sdata));
1727*4882a593Smuzhiyun
1728*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0A00000);
1729*4882a593Smuzhiyun fw->shadow_reg[10] = htonl(rd_reg_dword(®->iobase_sdata));
1730*4882a593Smuzhiyun
1731*4882a593Smuzhiyun /* RISC I/O register. */
1732*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x0010);
1733*4882a593Smuzhiyun fw->risc_io_reg = htonl(rd_reg_dword(®->iobase_window));
1734*4882a593Smuzhiyun
1735*4882a593Smuzhiyun /* Mailbox registers. */
1736*4882a593Smuzhiyun mbx_reg = ®->mailbox0;
1737*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
1738*4882a593Smuzhiyun fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg));
1739*4882a593Smuzhiyun
1740*4882a593Smuzhiyun /* Transfer sequence registers. */
1741*4882a593Smuzhiyun iter_reg = fw->xseq_gp_reg;
1742*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1743*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1744*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1745*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1746*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1747*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1748*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1749*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
1750*4882a593Smuzhiyun
1751*4882a593Smuzhiyun iter_reg = fw->xseq_0_reg;
1752*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
1753*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
1754*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
1755*4882a593Smuzhiyun
1756*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
1757*4882a593Smuzhiyun
1758*4882a593Smuzhiyun /* Receive sequence registers. */
1759*4882a593Smuzhiyun iter_reg = fw->rseq_gp_reg;
1760*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1761*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1762*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1763*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1764*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1765*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1766*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1767*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
1768*4882a593Smuzhiyun
1769*4882a593Smuzhiyun iter_reg = fw->rseq_0_reg;
1770*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
1771*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
1772*4882a593Smuzhiyun
1773*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1774*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
1775*4882a593Smuzhiyun
1776*4882a593Smuzhiyun /* Auxiliary sequence registers. */
1777*4882a593Smuzhiyun iter_reg = fw->aseq_gp_reg;
1778*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
1779*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
1780*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
1781*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
1782*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
1783*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
1784*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
1785*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB070, 16, iter_reg);
1786*4882a593Smuzhiyun
1787*4882a593Smuzhiyun iter_reg = fw->aseq_0_reg;
1788*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
1789*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
1790*4882a593Smuzhiyun
1791*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
1792*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
1793*4882a593Smuzhiyun
1794*4882a593Smuzhiyun /* Command DMA registers. */
1795*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
1796*4882a593Smuzhiyun
1797*4882a593Smuzhiyun /* Queues. */
1798*4882a593Smuzhiyun iter_reg = fw->req0_dma_reg;
1799*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1800*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
1801*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
1802*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
1803*4882a593Smuzhiyun
1804*4882a593Smuzhiyun iter_reg = fw->resp0_dma_reg;
1805*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1806*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
1807*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
1808*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
1809*4882a593Smuzhiyun
1810*4882a593Smuzhiyun iter_reg = fw->req1_dma_reg;
1811*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1812*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
1813*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
1814*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
1815*4882a593Smuzhiyun
1816*4882a593Smuzhiyun /* Transmit DMA registers. */
1817*4882a593Smuzhiyun iter_reg = fw->xmt0_dma_reg;
1818*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1819*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7610, 16, iter_reg);
1820*4882a593Smuzhiyun
1821*4882a593Smuzhiyun iter_reg = fw->xmt1_dma_reg;
1822*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1823*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7630, 16, iter_reg);
1824*4882a593Smuzhiyun
1825*4882a593Smuzhiyun iter_reg = fw->xmt2_dma_reg;
1826*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1827*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7650, 16, iter_reg);
1828*4882a593Smuzhiyun
1829*4882a593Smuzhiyun iter_reg = fw->xmt3_dma_reg;
1830*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1831*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7670, 16, iter_reg);
1832*4882a593Smuzhiyun
1833*4882a593Smuzhiyun iter_reg = fw->xmt4_dma_reg;
1834*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1835*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7690, 16, iter_reg);
1836*4882a593Smuzhiyun
1837*4882a593Smuzhiyun qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
1838*4882a593Smuzhiyun
1839*4882a593Smuzhiyun /* Receive DMA registers. */
1840*4882a593Smuzhiyun iter_reg = fw->rcvt0_data_dma_reg;
1841*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1842*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7710, 16, iter_reg);
1843*4882a593Smuzhiyun
1844*4882a593Smuzhiyun iter_reg = fw->rcvt1_data_dma_reg;
1845*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1846*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7730, 16, iter_reg);
1847*4882a593Smuzhiyun
1848*4882a593Smuzhiyun /* RISC registers. */
1849*4882a593Smuzhiyun iter_reg = fw->risc_gp_reg;
1850*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1851*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1852*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1853*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1854*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1855*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1856*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1857*4882a593Smuzhiyun qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
1858*4882a593Smuzhiyun
1859*4882a593Smuzhiyun /* Local memory controller registers. */
1860*4882a593Smuzhiyun iter_reg = fw->lmc_reg;
1861*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1862*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1863*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1864*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1865*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1866*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1867*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
1868*4882a593Smuzhiyun qla24xx_read_window(reg, 0x3070, 16, iter_reg);
1869*4882a593Smuzhiyun
1870*4882a593Smuzhiyun /* Fibre Protocol Module registers. */
1871*4882a593Smuzhiyun iter_reg = fw->fpm_hdw_reg;
1872*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1873*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1874*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1875*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1876*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1877*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1878*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1879*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1880*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1881*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1882*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1883*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
1884*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
1885*4882a593Smuzhiyun qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
1886*4882a593Smuzhiyun
1887*4882a593Smuzhiyun /* Frame Buffer registers. */
1888*4882a593Smuzhiyun iter_reg = fw->fb_hdw_reg;
1889*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1890*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1891*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1892*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1893*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1894*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1895*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1896*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1897*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1898*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1899*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
1900*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
1901*4882a593Smuzhiyun qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
1902*4882a593Smuzhiyun
1903*4882a593Smuzhiyun /* Multi queue registers */
1904*4882a593Smuzhiyun nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
1905*4882a593Smuzhiyun &last_chain);
1906*4882a593Smuzhiyun
1907*4882a593Smuzhiyun rval = qla24xx_soft_reset(ha);
1908*4882a593Smuzhiyun if (rval != QLA_SUCCESS)
1909*4882a593Smuzhiyun goto qla81xx_fw_dump_failed_0;
1910*4882a593Smuzhiyun
1911*4882a593Smuzhiyun rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
1912*4882a593Smuzhiyun &nxt);
1913*4882a593Smuzhiyun if (rval != QLA_SUCCESS)
1914*4882a593Smuzhiyun goto qla81xx_fw_dump_failed_0;
1915*4882a593Smuzhiyun
1916*4882a593Smuzhiyun nxt = qla2xxx_copy_queues(ha, nxt);
1917*4882a593Smuzhiyun
1918*4882a593Smuzhiyun qla24xx_copy_eft(ha, nxt);
1919*4882a593Smuzhiyun
1920*4882a593Smuzhiyun /* Chain entries -- started with MQ. */
1921*4882a593Smuzhiyun nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
1922*4882a593Smuzhiyun nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
1923*4882a593Smuzhiyun nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
1924*4882a593Smuzhiyun nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, &last_chain);
1925*4882a593Smuzhiyun nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, &last_chain);
1926*4882a593Smuzhiyun if (last_chain) {
1927*4882a593Smuzhiyun ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
1928*4882a593Smuzhiyun *last_chain |= htonl(DUMP_CHAIN_LAST);
1929*4882a593Smuzhiyun }
1930*4882a593Smuzhiyun
1931*4882a593Smuzhiyun /* Adjust valid length. */
1932*4882a593Smuzhiyun ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1933*4882a593Smuzhiyun
1934*4882a593Smuzhiyun qla81xx_fw_dump_failed_0:
1935*4882a593Smuzhiyun qla2xxx_dump_post_process(base_vha, rval);
1936*4882a593Smuzhiyun }
1937*4882a593Smuzhiyun
1938*4882a593Smuzhiyun void
qla83xx_fw_dump(scsi_qla_host_t * vha)1939*4882a593Smuzhiyun qla83xx_fw_dump(scsi_qla_host_t *vha)
1940*4882a593Smuzhiyun {
1941*4882a593Smuzhiyun int rval;
1942*4882a593Smuzhiyun uint32_t cnt;
1943*4882a593Smuzhiyun struct qla_hw_data *ha = vha->hw;
1944*4882a593Smuzhiyun struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1945*4882a593Smuzhiyun __le32 __iomem *dmp_reg;
1946*4882a593Smuzhiyun __be32 *iter_reg;
1947*4882a593Smuzhiyun __le16 __iomem *mbx_reg;
1948*4882a593Smuzhiyun struct qla83xx_fw_dump *fw;
1949*4882a593Smuzhiyun void *nxt, *nxt_chain;
1950*4882a593Smuzhiyun __be32 *last_chain = NULL;
1951*4882a593Smuzhiyun struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
1952*4882a593Smuzhiyun
1953*4882a593Smuzhiyun lockdep_assert_held(&ha->hardware_lock);
1954*4882a593Smuzhiyun
1955*4882a593Smuzhiyun ha->fw_dump_cap_flags = 0;
1956*4882a593Smuzhiyun
1957*4882a593Smuzhiyun if (!ha->fw_dump) {
1958*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd00c,
1959*4882a593Smuzhiyun "No buffer available for dump!!!\n");
1960*4882a593Smuzhiyun return;
1961*4882a593Smuzhiyun }
1962*4882a593Smuzhiyun
1963*4882a593Smuzhiyun if (ha->fw_dumped) {
1964*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd00d,
1965*4882a593Smuzhiyun "Firmware has been previously dumped (%p) -- ignoring "
1966*4882a593Smuzhiyun "request...\n", ha->fw_dump);
1967*4882a593Smuzhiyun return;
1968*4882a593Smuzhiyun }
1969*4882a593Smuzhiyun QLA_FW_STOPPED(ha);
1970*4882a593Smuzhiyun fw = &ha->fw_dump->isp.isp83;
1971*4882a593Smuzhiyun qla2xxx_prep_dump(ha, ha->fw_dump);
1972*4882a593Smuzhiyun
1973*4882a593Smuzhiyun fw->host_status = htonl(rd_reg_dword(®->host_status));
1974*4882a593Smuzhiyun
1975*4882a593Smuzhiyun /*
1976*4882a593Smuzhiyun * Pause RISC. No need to track timeout, as resetting the chip
1977*4882a593Smuzhiyun * is the right approach incase of pause timeout
1978*4882a593Smuzhiyun */
1979*4882a593Smuzhiyun qla24xx_pause_risc(reg, ha);
1980*4882a593Smuzhiyun
1981*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x6000);
1982*4882a593Smuzhiyun dmp_reg = ®->iobase_window;
1983*4882a593Smuzhiyun rd_reg_dword(dmp_reg);
1984*4882a593Smuzhiyun wrt_reg_dword(dmp_reg, 0);
1985*4882a593Smuzhiyun
1986*4882a593Smuzhiyun dmp_reg = ®->unused_4_1[0];
1987*4882a593Smuzhiyun rd_reg_dword(dmp_reg);
1988*4882a593Smuzhiyun wrt_reg_dword(dmp_reg, 0);
1989*4882a593Smuzhiyun
1990*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x6010);
1991*4882a593Smuzhiyun dmp_reg = ®->unused_4_1[2];
1992*4882a593Smuzhiyun rd_reg_dword(dmp_reg);
1993*4882a593Smuzhiyun wrt_reg_dword(dmp_reg, 0);
1994*4882a593Smuzhiyun
1995*4882a593Smuzhiyun /* select PCR and disable ecc checking and correction */
1996*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x0F70);
1997*4882a593Smuzhiyun rd_reg_dword(®->iobase_addr);
1998*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0x60000000); /* write to F0h = PCR */
1999*4882a593Smuzhiyun
2000*4882a593Smuzhiyun /* Host/Risc registers. */
2001*4882a593Smuzhiyun iter_reg = fw->host_risc_reg;
2002*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
2003*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7010, 16, iter_reg);
2004*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7040, 16, iter_reg);
2005*4882a593Smuzhiyun
2006*4882a593Smuzhiyun /* PCIe registers. */
2007*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x7C00);
2008*4882a593Smuzhiyun rd_reg_dword(®->iobase_addr);
2009*4882a593Smuzhiyun wrt_reg_dword(®->iobase_window, 0x01);
2010*4882a593Smuzhiyun dmp_reg = ®->iobase_c4;
2011*4882a593Smuzhiyun fw->pcie_regs[0] = htonl(rd_reg_dword(dmp_reg));
2012*4882a593Smuzhiyun dmp_reg++;
2013*4882a593Smuzhiyun fw->pcie_regs[1] = htonl(rd_reg_dword(dmp_reg));
2014*4882a593Smuzhiyun dmp_reg++;
2015*4882a593Smuzhiyun fw->pcie_regs[2] = htonl(rd_reg_dword(dmp_reg));
2016*4882a593Smuzhiyun fw->pcie_regs[3] = htonl(rd_reg_dword(®->iobase_window));
2017*4882a593Smuzhiyun
2018*4882a593Smuzhiyun wrt_reg_dword(®->iobase_window, 0x00);
2019*4882a593Smuzhiyun rd_reg_dword(®->iobase_window);
2020*4882a593Smuzhiyun
2021*4882a593Smuzhiyun /* Host interface registers. */
2022*4882a593Smuzhiyun dmp_reg = ®->flash_addr;
2023*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
2024*4882a593Smuzhiyun fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg));
2025*4882a593Smuzhiyun
2026*4882a593Smuzhiyun /* Disable interrupts. */
2027*4882a593Smuzhiyun wrt_reg_dword(®->ictrl, 0);
2028*4882a593Smuzhiyun rd_reg_dword(®->ictrl);
2029*4882a593Smuzhiyun
2030*4882a593Smuzhiyun /* Shadow registers. */
2031*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x0F70);
2032*4882a593Smuzhiyun rd_reg_dword(®->iobase_addr);
2033*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0000000);
2034*4882a593Smuzhiyun fw->shadow_reg[0] = htonl(rd_reg_dword(®->iobase_sdata));
2035*4882a593Smuzhiyun
2036*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0100000);
2037*4882a593Smuzhiyun fw->shadow_reg[1] = htonl(rd_reg_dword(®->iobase_sdata));
2038*4882a593Smuzhiyun
2039*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0200000);
2040*4882a593Smuzhiyun fw->shadow_reg[2] = htonl(rd_reg_dword(®->iobase_sdata));
2041*4882a593Smuzhiyun
2042*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0300000);
2043*4882a593Smuzhiyun fw->shadow_reg[3] = htonl(rd_reg_dword(®->iobase_sdata));
2044*4882a593Smuzhiyun
2045*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0400000);
2046*4882a593Smuzhiyun fw->shadow_reg[4] = htonl(rd_reg_dword(®->iobase_sdata));
2047*4882a593Smuzhiyun
2048*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0500000);
2049*4882a593Smuzhiyun fw->shadow_reg[5] = htonl(rd_reg_dword(®->iobase_sdata));
2050*4882a593Smuzhiyun
2051*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0600000);
2052*4882a593Smuzhiyun fw->shadow_reg[6] = htonl(rd_reg_dword(®->iobase_sdata));
2053*4882a593Smuzhiyun
2054*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0700000);
2055*4882a593Smuzhiyun fw->shadow_reg[7] = htonl(rd_reg_dword(®->iobase_sdata));
2056*4882a593Smuzhiyun
2057*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0800000);
2058*4882a593Smuzhiyun fw->shadow_reg[8] = htonl(rd_reg_dword(®->iobase_sdata));
2059*4882a593Smuzhiyun
2060*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0900000);
2061*4882a593Smuzhiyun fw->shadow_reg[9] = htonl(rd_reg_dword(®->iobase_sdata));
2062*4882a593Smuzhiyun
2063*4882a593Smuzhiyun wrt_reg_dword(®->iobase_select, 0xB0A00000);
2064*4882a593Smuzhiyun fw->shadow_reg[10] = htonl(rd_reg_dword(®->iobase_sdata));
2065*4882a593Smuzhiyun
2066*4882a593Smuzhiyun /* RISC I/O register. */
2067*4882a593Smuzhiyun wrt_reg_dword(®->iobase_addr, 0x0010);
2068*4882a593Smuzhiyun fw->risc_io_reg = htonl(rd_reg_dword(®->iobase_window));
2069*4882a593Smuzhiyun
2070*4882a593Smuzhiyun /* Mailbox registers. */
2071*4882a593Smuzhiyun mbx_reg = ®->mailbox0;
2072*4882a593Smuzhiyun for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
2073*4882a593Smuzhiyun fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg));
2074*4882a593Smuzhiyun
2075*4882a593Smuzhiyun /* Transfer sequence registers. */
2076*4882a593Smuzhiyun iter_reg = fw->xseq_gp_reg;
2077*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBE00, 16, iter_reg);
2078*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBE10, 16, iter_reg);
2079*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBE20, 16, iter_reg);
2080*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBE30, 16, iter_reg);
2081*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBE40, 16, iter_reg);
2082*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBE50, 16, iter_reg);
2083*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBE60, 16, iter_reg);
2084*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBE70, 16, iter_reg);
2085*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
2086*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
2087*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
2088*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
2089*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
2090*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
2091*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
2092*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
2093*4882a593Smuzhiyun
2094*4882a593Smuzhiyun iter_reg = fw->xseq_0_reg;
2095*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
2096*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
2097*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
2098*4882a593Smuzhiyun
2099*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
2100*4882a593Smuzhiyun
2101*4882a593Smuzhiyun qla24xx_read_window(reg, 0xBEF0, 16, fw->xseq_2_reg);
2102*4882a593Smuzhiyun
2103*4882a593Smuzhiyun /* Receive sequence registers. */
2104*4882a593Smuzhiyun iter_reg = fw->rseq_gp_reg;
2105*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFE00, 16, iter_reg);
2106*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFE10, 16, iter_reg);
2107*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFE20, 16, iter_reg);
2108*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFE30, 16, iter_reg);
2109*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFE40, 16, iter_reg);
2110*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFE50, 16, iter_reg);
2111*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFE60, 16, iter_reg);
2112*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFE70, 16, iter_reg);
2113*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
2114*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
2115*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
2116*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
2117*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
2118*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
2119*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
2120*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
2121*4882a593Smuzhiyun
2122*4882a593Smuzhiyun iter_reg = fw->rseq_0_reg;
2123*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
2124*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
2125*4882a593Smuzhiyun
2126*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
2127*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
2128*4882a593Smuzhiyun qla24xx_read_window(reg, 0xFEF0, 16, fw->rseq_3_reg);
2129*4882a593Smuzhiyun
2130*4882a593Smuzhiyun /* Auxiliary sequence registers. */
2131*4882a593Smuzhiyun iter_reg = fw->aseq_gp_reg;
2132*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
2133*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
2134*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
2135*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
2136*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
2137*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
2138*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
2139*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB070, 16, iter_reg);
2140*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB100, 16, iter_reg);
2141*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB110, 16, iter_reg);
2142*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB120, 16, iter_reg);
2143*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB130, 16, iter_reg);
2144*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB140, 16, iter_reg);
2145*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB150, 16, iter_reg);
2146*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB160, 16, iter_reg);
2147*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB170, 16, iter_reg);
2148*4882a593Smuzhiyun
2149*4882a593Smuzhiyun iter_reg = fw->aseq_0_reg;
2150*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
2151*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
2152*4882a593Smuzhiyun
2153*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
2154*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
2155*4882a593Smuzhiyun qla24xx_read_window(reg, 0xB1F0, 16, fw->aseq_3_reg);
2156*4882a593Smuzhiyun
2157*4882a593Smuzhiyun /* Command DMA registers. */
2158*4882a593Smuzhiyun iter_reg = fw->cmd_dma_reg;
2159*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7100, 16, iter_reg);
2160*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7120, 16, iter_reg);
2161*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7130, 16, iter_reg);
2162*4882a593Smuzhiyun qla24xx_read_window(reg, 0x71F0, 16, iter_reg);
2163*4882a593Smuzhiyun
2164*4882a593Smuzhiyun /* Queues. */
2165*4882a593Smuzhiyun iter_reg = fw->req0_dma_reg;
2166*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
2167*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
2168*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
2169*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
2170*4882a593Smuzhiyun
2171*4882a593Smuzhiyun iter_reg = fw->resp0_dma_reg;
2172*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
2173*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
2174*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
2175*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
2176*4882a593Smuzhiyun
2177*4882a593Smuzhiyun iter_reg = fw->req1_dma_reg;
2178*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
2179*4882a593Smuzhiyun dmp_reg = ®->iobase_q;
2180*4882a593Smuzhiyun for (cnt = 0; cnt < 7; cnt++, dmp_reg++)
2181*4882a593Smuzhiyun *iter_reg++ = htonl(rd_reg_dword(dmp_reg));
2182*4882a593Smuzhiyun
2183*4882a593Smuzhiyun /* Transmit DMA registers. */
2184*4882a593Smuzhiyun iter_reg = fw->xmt0_dma_reg;
2185*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
2186*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7610, 16, iter_reg);
2187*4882a593Smuzhiyun
2188*4882a593Smuzhiyun iter_reg = fw->xmt1_dma_reg;
2189*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
2190*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7630, 16, iter_reg);
2191*4882a593Smuzhiyun
2192*4882a593Smuzhiyun iter_reg = fw->xmt2_dma_reg;
2193*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
2194*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7650, 16, iter_reg);
2195*4882a593Smuzhiyun
2196*4882a593Smuzhiyun iter_reg = fw->xmt3_dma_reg;
2197*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
2198*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7670, 16, iter_reg);
2199*4882a593Smuzhiyun
2200*4882a593Smuzhiyun iter_reg = fw->xmt4_dma_reg;
2201*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
2202*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7690, 16, iter_reg);
2203*4882a593Smuzhiyun
2204*4882a593Smuzhiyun qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
2205*4882a593Smuzhiyun
2206*4882a593Smuzhiyun /* Receive DMA registers. */
2207*4882a593Smuzhiyun iter_reg = fw->rcvt0_data_dma_reg;
2208*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
2209*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7710, 16, iter_reg);
2210*4882a593Smuzhiyun
2211*4882a593Smuzhiyun iter_reg = fw->rcvt1_data_dma_reg;
2212*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
2213*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7730, 16, iter_reg);
2214*4882a593Smuzhiyun
2215*4882a593Smuzhiyun /* RISC registers. */
2216*4882a593Smuzhiyun iter_reg = fw->risc_gp_reg;
2217*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
2218*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
2219*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
2220*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
2221*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
2222*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
2223*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
2224*4882a593Smuzhiyun qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
2225*4882a593Smuzhiyun
2226*4882a593Smuzhiyun /* Local memory controller registers. */
2227*4882a593Smuzhiyun iter_reg = fw->lmc_reg;
2228*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
2229*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
2230*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
2231*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
2232*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
2233*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
2234*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
2235*4882a593Smuzhiyun qla24xx_read_window(reg, 0x3070, 16, iter_reg);
2236*4882a593Smuzhiyun
2237*4882a593Smuzhiyun /* Fibre Protocol Module registers. */
2238*4882a593Smuzhiyun iter_reg = fw->fpm_hdw_reg;
2239*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
2240*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
2241*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
2242*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
2243*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
2244*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
2245*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
2246*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
2247*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
2248*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
2249*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
2250*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
2251*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
2252*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
2253*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x40E0, 16, iter_reg);
2254*4882a593Smuzhiyun qla24xx_read_window(reg, 0x40F0, 16, iter_reg);
2255*4882a593Smuzhiyun
2256*4882a593Smuzhiyun /* RQ0 Array registers. */
2257*4882a593Smuzhiyun iter_reg = fw->rq0_array_reg;
2258*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5C00, 16, iter_reg);
2259*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5C10, 16, iter_reg);
2260*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5C20, 16, iter_reg);
2261*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5C30, 16, iter_reg);
2262*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5C40, 16, iter_reg);
2263*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5C50, 16, iter_reg);
2264*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5C60, 16, iter_reg);
2265*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5C70, 16, iter_reg);
2266*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5C80, 16, iter_reg);
2267*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5C90, 16, iter_reg);
2268*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5CA0, 16, iter_reg);
2269*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5CB0, 16, iter_reg);
2270*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5CC0, 16, iter_reg);
2271*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5CD0, 16, iter_reg);
2272*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5CE0, 16, iter_reg);
2273*4882a593Smuzhiyun qla24xx_read_window(reg, 0x5CF0, 16, iter_reg);
2274*4882a593Smuzhiyun
2275*4882a593Smuzhiyun /* RQ1 Array registers. */
2276*4882a593Smuzhiyun iter_reg = fw->rq1_array_reg;
2277*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5D00, 16, iter_reg);
2278*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5D10, 16, iter_reg);
2279*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5D20, 16, iter_reg);
2280*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5D30, 16, iter_reg);
2281*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5D40, 16, iter_reg);
2282*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5D50, 16, iter_reg);
2283*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5D60, 16, iter_reg);
2284*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5D70, 16, iter_reg);
2285*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5D80, 16, iter_reg);
2286*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5D90, 16, iter_reg);
2287*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5DA0, 16, iter_reg);
2288*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5DB0, 16, iter_reg);
2289*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5DC0, 16, iter_reg);
2290*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5DD0, 16, iter_reg);
2291*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5DE0, 16, iter_reg);
2292*4882a593Smuzhiyun qla24xx_read_window(reg, 0x5DF0, 16, iter_reg);
2293*4882a593Smuzhiyun
2294*4882a593Smuzhiyun /* RP0 Array registers. */
2295*4882a593Smuzhiyun iter_reg = fw->rp0_array_reg;
2296*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5E00, 16, iter_reg);
2297*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5E10, 16, iter_reg);
2298*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5E20, 16, iter_reg);
2299*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5E30, 16, iter_reg);
2300*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5E40, 16, iter_reg);
2301*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5E50, 16, iter_reg);
2302*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5E60, 16, iter_reg);
2303*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5E70, 16, iter_reg);
2304*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5E80, 16, iter_reg);
2305*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5E90, 16, iter_reg);
2306*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5EA0, 16, iter_reg);
2307*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5EB0, 16, iter_reg);
2308*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5EC0, 16, iter_reg);
2309*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5ED0, 16, iter_reg);
2310*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5EE0, 16, iter_reg);
2311*4882a593Smuzhiyun qla24xx_read_window(reg, 0x5EF0, 16, iter_reg);
2312*4882a593Smuzhiyun
2313*4882a593Smuzhiyun /* RP1 Array registers. */
2314*4882a593Smuzhiyun iter_reg = fw->rp1_array_reg;
2315*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5F00, 16, iter_reg);
2316*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5F10, 16, iter_reg);
2317*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5F20, 16, iter_reg);
2318*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5F30, 16, iter_reg);
2319*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5F40, 16, iter_reg);
2320*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5F50, 16, iter_reg);
2321*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5F60, 16, iter_reg);
2322*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5F70, 16, iter_reg);
2323*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5F80, 16, iter_reg);
2324*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5F90, 16, iter_reg);
2325*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5FA0, 16, iter_reg);
2326*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5FB0, 16, iter_reg);
2327*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5FC0, 16, iter_reg);
2328*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5FD0, 16, iter_reg);
2329*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x5FE0, 16, iter_reg);
2330*4882a593Smuzhiyun qla24xx_read_window(reg, 0x5FF0, 16, iter_reg);
2331*4882a593Smuzhiyun
2332*4882a593Smuzhiyun iter_reg = fw->at0_array_reg;
2333*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7080, 16, iter_reg);
2334*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x7090, 16, iter_reg);
2335*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x70A0, 16, iter_reg);
2336*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x70B0, 16, iter_reg);
2337*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x70C0, 16, iter_reg);
2338*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x70D0, 16, iter_reg);
2339*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x70E0, 16, iter_reg);
2340*4882a593Smuzhiyun qla24xx_read_window(reg, 0x70F0, 16, iter_reg);
2341*4882a593Smuzhiyun
2342*4882a593Smuzhiyun /* I/O Queue Control registers. */
2343*4882a593Smuzhiyun qla24xx_read_window(reg, 0x7800, 16, fw->queue_control_reg);
2344*4882a593Smuzhiyun
2345*4882a593Smuzhiyun /* Frame Buffer registers. */
2346*4882a593Smuzhiyun iter_reg = fw->fb_hdw_reg;
2347*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
2348*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
2349*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
2350*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
2351*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
2352*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6060, 16, iter_reg);
2353*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6070, 16, iter_reg);
2354*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
2355*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
2356*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
2357*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
2358*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
2359*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
2360*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
2361*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6530, 16, iter_reg);
2362*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6540, 16, iter_reg);
2363*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6550, 16, iter_reg);
2364*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6560, 16, iter_reg);
2365*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6570, 16, iter_reg);
2366*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6580, 16, iter_reg);
2367*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x6590, 16, iter_reg);
2368*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x65A0, 16, iter_reg);
2369*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x65B0, 16, iter_reg);
2370*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x65C0, 16, iter_reg);
2371*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x65D0, 16, iter_reg);
2372*4882a593Smuzhiyun iter_reg = qla24xx_read_window(reg, 0x65E0, 16, iter_reg);
2373*4882a593Smuzhiyun qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
2374*4882a593Smuzhiyun
2375*4882a593Smuzhiyun /* Multi queue registers */
2376*4882a593Smuzhiyun nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
2377*4882a593Smuzhiyun &last_chain);
2378*4882a593Smuzhiyun
2379*4882a593Smuzhiyun rval = qla24xx_soft_reset(ha);
2380*4882a593Smuzhiyun if (rval != QLA_SUCCESS) {
2381*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd00e,
2382*4882a593Smuzhiyun "SOFT RESET FAILED, forcing continuation of dump!!!\n");
2383*4882a593Smuzhiyun rval = QLA_SUCCESS;
2384*4882a593Smuzhiyun
2385*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd00f, "try a bigger hammer!!!\n");
2386*4882a593Smuzhiyun
2387*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_SET_RISC_RESET);
2388*4882a593Smuzhiyun rd_reg_dword(®->hccr);
2389*4882a593Smuzhiyun
2390*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_REL_RISC_PAUSE);
2391*4882a593Smuzhiyun rd_reg_dword(®->hccr);
2392*4882a593Smuzhiyun
2393*4882a593Smuzhiyun wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_RESET);
2394*4882a593Smuzhiyun rd_reg_dword(®->hccr);
2395*4882a593Smuzhiyun
2396*4882a593Smuzhiyun for (cnt = 30000; cnt && (rd_reg_word(®->mailbox0)); cnt--)
2397*4882a593Smuzhiyun udelay(5);
2398*4882a593Smuzhiyun
2399*4882a593Smuzhiyun if (!cnt) {
2400*4882a593Smuzhiyun nxt = fw->code_ram;
2401*4882a593Smuzhiyun nxt += sizeof(fw->code_ram);
2402*4882a593Smuzhiyun nxt += (ha->fw_memory_size - 0x100000 + 1);
2403*4882a593Smuzhiyun goto copy_queue;
2404*4882a593Smuzhiyun } else {
2405*4882a593Smuzhiyun set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
2406*4882a593Smuzhiyun ql_log(ql_log_warn, vha, 0xd010,
2407*4882a593Smuzhiyun "bigger hammer success?\n");
2408*4882a593Smuzhiyun }
2409*4882a593Smuzhiyun }
2410*4882a593Smuzhiyun
2411*4882a593Smuzhiyun rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
2412*4882a593Smuzhiyun &nxt);
2413*4882a593Smuzhiyun if (rval != QLA_SUCCESS)
2414*4882a593Smuzhiyun goto qla83xx_fw_dump_failed_0;
2415*4882a593Smuzhiyun
2416*4882a593Smuzhiyun copy_queue:
2417*4882a593Smuzhiyun nxt = qla2xxx_copy_queues(ha, nxt);
2418*4882a593Smuzhiyun
2419*4882a593Smuzhiyun qla24xx_copy_eft(ha, nxt);
2420*4882a593Smuzhiyun
2421*4882a593Smuzhiyun /* Chain entries -- started with MQ. */
2422*4882a593Smuzhiyun nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
2423*4882a593Smuzhiyun nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
2424*4882a593Smuzhiyun nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
2425*4882a593Smuzhiyun nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, &last_chain);
2426*4882a593Smuzhiyun nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, &last_chain);
2427*4882a593Smuzhiyun if (last_chain) {
2428*4882a593Smuzhiyun ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
2429*4882a593Smuzhiyun *last_chain |= htonl(DUMP_CHAIN_LAST);
2430*4882a593Smuzhiyun }
2431*4882a593Smuzhiyun
2432*4882a593Smuzhiyun /* Adjust valid length. */
2433*4882a593Smuzhiyun ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
2434*4882a593Smuzhiyun
2435*4882a593Smuzhiyun qla83xx_fw_dump_failed_0:
2436*4882a593Smuzhiyun qla2xxx_dump_post_process(base_vha, rval);
2437*4882a593Smuzhiyun }
2438*4882a593Smuzhiyun
2439*4882a593Smuzhiyun /****************************************************************************/
2440*4882a593Smuzhiyun /* Driver Debug Functions. */
2441*4882a593Smuzhiyun /****************************************************************************/
2442*4882a593Smuzhiyun
2443*4882a593Smuzhiyun /* Write the debug message prefix into @pbuf. */
ql_dbg_prefix(char * pbuf,int pbuf_size,const scsi_qla_host_t * vha,uint msg_id)2444*4882a593Smuzhiyun static void ql_dbg_prefix(char *pbuf, int pbuf_size,
2445*4882a593Smuzhiyun const scsi_qla_host_t *vha, uint msg_id)
2446*4882a593Smuzhiyun {
2447*4882a593Smuzhiyun if (vha) {
2448*4882a593Smuzhiyun const struct pci_dev *pdev = vha->hw->pdev;
2449*4882a593Smuzhiyun
2450*4882a593Smuzhiyun /* <module-name> [<dev-name>]-<msg-id>:<host>: */
2451*4882a593Smuzhiyun snprintf(pbuf, pbuf_size, "%s [%s]-%04x:%lu: ", QL_MSGHDR,
2452*4882a593Smuzhiyun dev_name(&(pdev->dev)), msg_id, vha->host_no);
2453*4882a593Smuzhiyun } else {
2454*4882a593Smuzhiyun /* <module-name> [<dev-name>]-<msg-id>: : */
2455*4882a593Smuzhiyun snprintf(pbuf, pbuf_size, "%s [%s]-%04x: : ", QL_MSGHDR,
2456*4882a593Smuzhiyun "0000:00:00.0", msg_id);
2457*4882a593Smuzhiyun }
2458*4882a593Smuzhiyun }
2459*4882a593Smuzhiyun
2460*4882a593Smuzhiyun /*
2461*4882a593Smuzhiyun * This function is for formatting and logging debug information.
2462*4882a593Smuzhiyun * It is to be used when vha is available. It formats the message
2463*4882a593Smuzhiyun * and logs it to the messages file.
2464*4882a593Smuzhiyun * parameters:
2465*4882a593Smuzhiyun * level: The level of the debug messages to be printed.
2466*4882a593Smuzhiyun * If ql2xextended_error_logging value is correctly set,
2467*4882a593Smuzhiyun * this message will appear in the messages file.
2468*4882a593Smuzhiyun * vha: Pointer to the scsi_qla_host_t.
2469*4882a593Smuzhiyun * id: This is a unique identifier for the level. It identifies the
2470*4882a593Smuzhiyun * part of the code from where the message originated.
2471*4882a593Smuzhiyun * msg: The message to be displayed.
2472*4882a593Smuzhiyun */
2473*4882a593Smuzhiyun void
ql_dbg(uint level,scsi_qla_host_t * vha,uint id,const char * fmt,...)2474*4882a593Smuzhiyun ql_dbg(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...)
2475*4882a593Smuzhiyun {
2476*4882a593Smuzhiyun va_list va;
2477*4882a593Smuzhiyun struct va_format vaf;
2478*4882a593Smuzhiyun char pbuf[64];
2479*4882a593Smuzhiyun
2480*4882a593Smuzhiyun if (!ql_mask_match(level) && !trace_ql_dbg_log_enabled())
2481*4882a593Smuzhiyun return;
2482*4882a593Smuzhiyun
2483*4882a593Smuzhiyun va_start(va, fmt);
2484*4882a593Smuzhiyun
2485*4882a593Smuzhiyun vaf.fmt = fmt;
2486*4882a593Smuzhiyun vaf.va = &va;
2487*4882a593Smuzhiyun
2488*4882a593Smuzhiyun ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), vha, id);
2489*4882a593Smuzhiyun
2490*4882a593Smuzhiyun if (!ql_mask_match(level))
2491*4882a593Smuzhiyun trace_ql_dbg_log(pbuf, &vaf);
2492*4882a593Smuzhiyun else
2493*4882a593Smuzhiyun pr_warn("%s%pV", pbuf, &vaf);
2494*4882a593Smuzhiyun
2495*4882a593Smuzhiyun va_end(va);
2496*4882a593Smuzhiyun
2497*4882a593Smuzhiyun }
2498*4882a593Smuzhiyun
2499*4882a593Smuzhiyun /*
2500*4882a593Smuzhiyun * This function is for formatting and logging debug information.
2501*4882a593Smuzhiyun * It is to be used when vha is not available and pci is available,
2502*4882a593Smuzhiyun * i.e., before host allocation. It formats the message and logs it
2503*4882a593Smuzhiyun * to the messages file.
2504*4882a593Smuzhiyun * parameters:
2505*4882a593Smuzhiyun * level: The level of the debug messages to be printed.
2506*4882a593Smuzhiyun * If ql2xextended_error_logging value is correctly set,
2507*4882a593Smuzhiyun * this message will appear in the messages file.
2508*4882a593Smuzhiyun * pdev: Pointer to the struct pci_dev.
2509*4882a593Smuzhiyun * id: This is a unique id for the level. It identifies the part
2510*4882a593Smuzhiyun * of the code from where the message originated.
2511*4882a593Smuzhiyun * msg: The message to be displayed.
2512*4882a593Smuzhiyun */
2513*4882a593Smuzhiyun void
ql_dbg_pci(uint level,struct pci_dev * pdev,uint id,const char * fmt,...)2514*4882a593Smuzhiyun ql_dbg_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...)
2515*4882a593Smuzhiyun {
2516*4882a593Smuzhiyun va_list va;
2517*4882a593Smuzhiyun struct va_format vaf;
2518*4882a593Smuzhiyun char pbuf[128];
2519*4882a593Smuzhiyun
2520*4882a593Smuzhiyun if (pdev == NULL)
2521*4882a593Smuzhiyun return;
2522*4882a593Smuzhiyun if (!ql_mask_match(level))
2523*4882a593Smuzhiyun return;
2524*4882a593Smuzhiyun
2525*4882a593Smuzhiyun va_start(va, fmt);
2526*4882a593Smuzhiyun
2527*4882a593Smuzhiyun vaf.fmt = fmt;
2528*4882a593Smuzhiyun vaf.va = &va;
2529*4882a593Smuzhiyun
2530*4882a593Smuzhiyun ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, id + ql_dbg_offset);
2531*4882a593Smuzhiyun pr_warn("%s%pV", pbuf, &vaf);
2532*4882a593Smuzhiyun
2533*4882a593Smuzhiyun va_end(va);
2534*4882a593Smuzhiyun }
2535*4882a593Smuzhiyun
2536*4882a593Smuzhiyun /*
2537*4882a593Smuzhiyun * This function is for formatting and logging log messages.
2538*4882a593Smuzhiyun * It is to be used when vha is available. It formats the message
2539*4882a593Smuzhiyun * and logs it to the messages file. All the messages will be logged
2540*4882a593Smuzhiyun * irrespective of value of ql2xextended_error_logging.
2541*4882a593Smuzhiyun * parameters:
2542*4882a593Smuzhiyun * level: The level of the log messages to be printed in the
2543*4882a593Smuzhiyun * messages file.
2544*4882a593Smuzhiyun * vha: Pointer to the scsi_qla_host_t
2545*4882a593Smuzhiyun * id: This is a unique id for the level. It identifies the
2546*4882a593Smuzhiyun * part of the code from where the message originated.
2547*4882a593Smuzhiyun * msg: The message to be displayed.
2548*4882a593Smuzhiyun */
2549*4882a593Smuzhiyun void
ql_log(uint level,scsi_qla_host_t * vha,uint id,const char * fmt,...)2550*4882a593Smuzhiyun ql_log(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...)
2551*4882a593Smuzhiyun {
2552*4882a593Smuzhiyun va_list va;
2553*4882a593Smuzhiyun struct va_format vaf;
2554*4882a593Smuzhiyun char pbuf[128];
2555*4882a593Smuzhiyun
2556*4882a593Smuzhiyun if (level > ql_errlev)
2557*4882a593Smuzhiyun return;
2558*4882a593Smuzhiyun
2559*4882a593Smuzhiyun ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), vha, id);
2560*4882a593Smuzhiyun
2561*4882a593Smuzhiyun va_start(va, fmt);
2562*4882a593Smuzhiyun
2563*4882a593Smuzhiyun vaf.fmt = fmt;
2564*4882a593Smuzhiyun vaf.va = &va;
2565*4882a593Smuzhiyun
2566*4882a593Smuzhiyun switch (level) {
2567*4882a593Smuzhiyun case ql_log_fatal: /* FATAL LOG */
2568*4882a593Smuzhiyun pr_crit("%s%pV", pbuf, &vaf);
2569*4882a593Smuzhiyun break;
2570*4882a593Smuzhiyun case ql_log_warn:
2571*4882a593Smuzhiyun pr_err("%s%pV", pbuf, &vaf);
2572*4882a593Smuzhiyun break;
2573*4882a593Smuzhiyun case ql_log_info:
2574*4882a593Smuzhiyun pr_warn("%s%pV", pbuf, &vaf);
2575*4882a593Smuzhiyun break;
2576*4882a593Smuzhiyun default:
2577*4882a593Smuzhiyun pr_info("%s%pV", pbuf, &vaf);
2578*4882a593Smuzhiyun break;
2579*4882a593Smuzhiyun }
2580*4882a593Smuzhiyun
2581*4882a593Smuzhiyun va_end(va);
2582*4882a593Smuzhiyun }
2583*4882a593Smuzhiyun
2584*4882a593Smuzhiyun /*
2585*4882a593Smuzhiyun * This function is for formatting and logging log messages.
2586*4882a593Smuzhiyun * It is to be used when vha is not available and pci is available,
2587*4882a593Smuzhiyun * i.e., before host allocation. It formats the message and logs
2588*4882a593Smuzhiyun * it to the messages file. All the messages are logged irrespective
2589*4882a593Smuzhiyun * of the value of ql2xextended_error_logging.
2590*4882a593Smuzhiyun * parameters:
2591*4882a593Smuzhiyun * level: The level of the log messages to be printed in the
2592*4882a593Smuzhiyun * messages file.
2593*4882a593Smuzhiyun * pdev: Pointer to the struct pci_dev.
2594*4882a593Smuzhiyun * id: This is a unique id for the level. It identifies the
2595*4882a593Smuzhiyun * part of the code from where the message originated.
2596*4882a593Smuzhiyun * msg: The message to be displayed.
2597*4882a593Smuzhiyun */
2598*4882a593Smuzhiyun void
ql_log_pci(uint level,struct pci_dev * pdev,uint id,const char * fmt,...)2599*4882a593Smuzhiyun ql_log_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...)
2600*4882a593Smuzhiyun {
2601*4882a593Smuzhiyun va_list va;
2602*4882a593Smuzhiyun struct va_format vaf;
2603*4882a593Smuzhiyun char pbuf[128];
2604*4882a593Smuzhiyun
2605*4882a593Smuzhiyun if (pdev == NULL)
2606*4882a593Smuzhiyun return;
2607*4882a593Smuzhiyun if (level > ql_errlev)
2608*4882a593Smuzhiyun return;
2609*4882a593Smuzhiyun
2610*4882a593Smuzhiyun ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, id);
2611*4882a593Smuzhiyun
2612*4882a593Smuzhiyun va_start(va, fmt);
2613*4882a593Smuzhiyun
2614*4882a593Smuzhiyun vaf.fmt = fmt;
2615*4882a593Smuzhiyun vaf.va = &va;
2616*4882a593Smuzhiyun
2617*4882a593Smuzhiyun switch (level) {
2618*4882a593Smuzhiyun case ql_log_fatal: /* FATAL LOG */
2619*4882a593Smuzhiyun pr_crit("%s%pV", pbuf, &vaf);
2620*4882a593Smuzhiyun break;
2621*4882a593Smuzhiyun case ql_log_warn:
2622*4882a593Smuzhiyun pr_err("%s%pV", pbuf, &vaf);
2623*4882a593Smuzhiyun break;
2624*4882a593Smuzhiyun case ql_log_info:
2625*4882a593Smuzhiyun pr_warn("%s%pV", pbuf, &vaf);
2626*4882a593Smuzhiyun break;
2627*4882a593Smuzhiyun default:
2628*4882a593Smuzhiyun pr_info("%s%pV", pbuf, &vaf);
2629*4882a593Smuzhiyun break;
2630*4882a593Smuzhiyun }
2631*4882a593Smuzhiyun
2632*4882a593Smuzhiyun va_end(va);
2633*4882a593Smuzhiyun }
2634*4882a593Smuzhiyun
2635*4882a593Smuzhiyun void
ql_dump_regs(uint level,scsi_qla_host_t * vha,uint id)2636*4882a593Smuzhiyun ql_dump_regs(uint level, scsi_qla_host_t *vha, uint id)
2637*4882a593Smuzhiyun {
2638*4882a593Smuzhiyun int i;
2639*4882a593Smuzhiyun struct qla_hw_data *ha = vha->hw;
2640*4882a593Smuzhiyun struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
2641*4882a593Smuzhiyun struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
2642*4882a593Smuzhiyun struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
2643*4882a593Smuzhiyun __le16 __iomem *mbx_reg;
2644*4882a593Smuzhiyun
2645*4882a593Smuzhiyun if (!ql_mask_match(level))
2646*4882a593Smuzhiyun return;
2647*4882a593Smuzhiyun
2648*4882a593Smuzhiyun if (IS_P3P_TYPE(ha))
2649*4882a593Smuzhiyun mbx_reg = ®82->mailbox_in[0];
2650*4882a593Smuzhiyun else if (IS_FWI2_CAPABLE(ha))
2651*4882a593Smuzhiyun mbx_reg = ®24->mailbox0;
2652*4882a593Smuzhiyun else
2653*4882a593Smuzhiyun mbx_reg = MAILBOX_REG(ha, reg, 0);
2654*4882a593Smuzhiyun
2655*4882a593Smuzhiyun ql_dbg(level, vha, id, "Mailbox registers:\n");
2656*4882a593Smuzhiyun for (i = 0; i < 6; i++, mbx_reg++)
2657*4882a593Smuzhiyun ql_dbg(level, vha, id,
2658*4882a593Smuzhiyun "mbox[%d] %#04x\n", i, rd_reg_word(mbx_reg));
2659*4882a593Smuzhiyun }
2660*4882a593Smuzhiyun
2661*4882a593Smuzhiyun void
ql_dump_buffer(uint level,scsi_qla_host_t * vha,uint id,const void * buf,uint size)2662*4882a593Smuzhiyun ql_dump_buffer(uint level, scsi_qla_host_t *vha, uint id, const void *buf,
2663*4882a593Smuzhiyun uint size)
2664*4882a593Smuzhiyun {
2665*4882a593Smuzhiyun uint cnt;
2666*4882a593Smuzhiyun
2667*4882a593Smuzhiyun if (!ql_mask_match(level))
2668*4882a593Smuzhiyun return;
2669*4882a593Smuzhiyun
2670*4882a593Smuzhiyun ql_dbg(level, vha, id,
2671*4882a593Smuzhiyun "%-+5d 0 1 2 3 4 5 6 7 8 9 A B C D E F\n", size);
2672*4882a593Smuzhiyun ql_dbg(level, vha, id,
2673*4882a593Smuzhiyun "----- -----------------------------------------------\n");
2674*4882a593Smuzhiyun for (cnt = 0; cnt < size; cnt += 16) {
2675*4882a593Smuzhiyun ql_dbg(level, vha, id, "%04x: ", cnt);
2676*4882a593Smuzhiyun print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1,
2677*4882a593Smuzhiyun buf + cnt, min(16U, size - cnt), false);
2678*4882a593Smuzhiyun }
2679*4882a593Smuzhiyun }
2680*4882a593Smuzhiyun
2681*4882a593Smuzhiyun /*
2682*4882a593Smuzhiyun * This function is for formatting and logging log messages.
2683*4882a593Smuzhiyun * It is to be used when vha is available. It formats the message
2684*4882a593Smuzhiyun * and logs it to the messages file. All the messages will be logged
2685*4882a593Smuzhiyun * irrespective of value of ql2xextended_error_logging.
2686*4882a593Smuzhiyun * parameters:
2687*4882a593Smuzhiyun * level: The level of the log messages to be printed in the
2688*4882a593Smuzhiyun * messages file.
2689*4882a593Smuzhiyun * vha: Pointer to the scsi_qla_host_t
2690*4882a593Smuzhiyun * id: This is a unique id for the level. It identifies the
2691*4882a593Smuzhiyun * part of the code from where the message originated.
2692*4882a593Smuzhiyun * msg: The message to be displayed.
2693*4882a593Smuzhiyun */
2694*4882a593Smuzhiyun void
ql_log_qp(uint32_t level,struct qla_qpair * qpair,int32_t id,const char * fmt,...)2695*4882a593Smuzhiyun ql_log_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
2696*4882a593Smuzhiyun const char *fmt, ...)
2697*4882a593Smuzhiyun {
2698*4882a593Smuzhiyun va_list va;
2699*4882a593Smuzhiyun struct va_format vaf;
2700*4882a593Smuzhiyun char pbuf[128];
2701*4882a593Smuzhiyun
2702*4882a593Smuzhiyun if (level > ql_errlev)
2703*4882a593Smuzhiyun return;
2704*4882a593Smuzhiyun
2705*4882a593Smuzhiyun ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), qpair ? qpair->vha : NULL, id);
2706*4882a593Smuzhiyun
2707*4882a593Smuzhiyun va_start(va, fmt);
2708*4882a593Smuzhiyun
2709*4882a593Smuzhiyun vaf.fmt = fmt;
2710*4882a593Smuzhiyun vaf.va = &va;
2711*4882a593Smuzhiyun
2712*4882a593Smuzhiyun switch (level) {
2713*4882a593Smuzhiyun case ql_log_fatal: /* FATAL LOG */
2714*4882a593Smuzhiyun pr_crit("%s%pV", pbuf, &vaf);
2715*4882a593Smuzhiyun break;
2716*4882a593Smuzhiyun case ql_log_warn:
2717*4882a593Smuzhiyun pr_err("%s%pV", pbuf, &vaf);
2718*4882a593Smuzhiyun break;
2719*4882a593Smuzhiyun case ql_log_info:
2720*4882a593Smuzhiyun pr_warn("%s%pV", pbuf, &vaf);
2721*4882a593Smuzhiyun break;
2722*4882a593Smuzhiyun default:
2723*4882a593Smuzhiyun pr_info("%s%pV", pbuf, &vaf);
2724*4882a593Smuzhiyun break;
2725*4882a593Smuzhiyun }
2726*4882a593Smuzhiyun
2727*4882a593Smuzhiyun va_end(va);
2728*4882a593Smuzhiyun }
2729*4882a593Smuzhiyun
2730*4882a593Smuzhiyun /*
2731*4882a593Smuzhiyun * This function is for formatting and logging debug information.
2732*4882a593Smuzhiyun * It is to be used when vha is available. It formats the message
2733*4882a593Smuzhiyun * and logs it to the messages file.
2734*4882a593Smuzhiyun * parameters:
2735*4882a593Smuzhiyun * level: The level of the debug messages to be printed.
2736*4882a593Smuzhiyun * If ql2xextended_error_logging value is correctly set,
2737*4882a593Smuzhiyun * this message will appear in the messages file.
2738*4882a593Smuzhiyun * vha: Pointer to the scsi_qla_host_t.
2739*4882a593Smuzhiyun * id: This is a unique identifier for the level. It identifies the
2740*4882a593Smuzhiyun * part of the code from where the message originated.
2741*4882a593Smuzhiyun * msg: The message to be displayed.
2742*4882a593Smuzhiyun */
2743*4882a593Smuzhiyun void
ql_dbg_qp(uint32_t level,struct qla_qpair * qpair,int32_t id,const char * fmt,...)2744*4882a593Smuzhiyun ql_dbg_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
2745*4882a593Smuzhiyun const char *fmt, ...)
2746*4882a593Smuzhiyun {
2747*4882a593Smuzhiyun va_list va;
2748*4882a593Smuzhiyun struct va_format vaf;
2749*4882a593Smuzhiyun char pbuf[128];
2750*4882a593Smuzhiyun
2751*4882a593Smuzhiyun if (!ql_mask_match(level))
2752*4882a593Smuzhiyun return;
2753*4882a593Smuzhiyun
2754*4882a593Smuzhiyun va_start(va, fmt);
2755*4882a593Smuzhiyun
2756*4882a593Smuzhiyun vaf.fmt = fmt;
2757*4882a593Smuzhiyun vaf.va = &va;
2758*4882a593Smuzhiyun
2759*4882a593Smuzhiyun ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), qpair ? qpair->vha : NULL,
2760*4882a593Smuzhiyun id + ql_dbg_offset);
2761*4882a593Smuzhiyun pr_warn("%s%pV", pbuf, &vaf);
2762*4882a593Smuzhiyun
2763*4882a593Smuzhiyun va_end(va);
2764*4882a593Smuzhiyun
2765*4882a593Smuzhiyun }
2766