blob: 156f5341a7a3f0bc106d6e8c20a9dbdfe2573868 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Andrew Vasquez07e264b2011-03-30 11:46:23 -07003 * Copyright (c) 2003-2011 QLogic Corporation
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
Andrew Vasquezfa90c542005-10-27 11:10:08 -07005 * See LICENSE.qla2xxx for copyright and licensing details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 */
Saurav Kashyap3ce88662011-07-14 12:00:12 -07007
8/*
9 * Table for showing the current message id in use for particular level
10 * Change this table for addition of log/debug messages.
Arun Easie02587d2011-08-16 11:29:23 -070011 * ----------------------------------------------------------------------
12 * | Level | Last Value Used | Holes |
13 * ----------------------------------------------------------------------
Chad Dupuis5f16b332012-08-22 14:21:00 -040014 * | Module Init and Probe | 0x0123 | 0x4b,0xba,0xfa |
Nicholas Bellinger2d70c102012-05-15 14:34:28 -040015 * | Mailbox commands | 0x1140 | 0x111a-0x111b |
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -040016 * | | | 0x112c-0x112e |
Andrew Vasquezaf11f642012-02-09 11:15:43 -080017 * | | | 0x113a |
Saurav Kashyapa9b6f722012-08-22 14:21:01 -040018 * | Device Discovery | 0x2087 | 0x2020-0x2022 |
Giridhar Malavali4aee5762012-04-25 07:26:15 -070019 * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 |
Giridhar Malavali6246b8a2012-02-09 11:15:34 -080020 * | | | 0x302d-0x302e |
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -040021 * | DPC Thread | 0x401c | 0x4002,0x4013 |
Chad Dupuisdaae62a2012-05-15 14:34:23 -040022 * | Async Events | 0x505f | 0x502b-0x502f |
Giridhar Malavali9ba56b92012-02-09 11:15:36 -080023 * | | | 0x5047,0x5052 |
Giridhar Malavali5988aeb2012-05-15 14:34:12 -040024 * | Timer Routines | 0x6011 | |
Saurav Kashyapa9b6f722012-08-22 14:21:01 -040025 * | User Space Interactions | 0x70bb | 0x7018,0x702e, |
Joe Carnuccio733a95b2012-02-09 11:15:55 -080026 * | | | 0x7039,0x7045, |
27 * | | | 0x7073-0x7075, |
Saurav Kashyapa9b6f722012-08-22 14:21:01 -040028 * | | | 0x708c, |
29 * | | | 0x70a5,0x70a6, |
30 * | | | 0x70a8,0x70ab, |
31 * | | | 0x70ad-0x70ae |
Chad Dupuiscfb09192011-11-18 09:03:07 -080032 * | Task Management | 0x803c | 0x8025-0x8026 |
33 * | | | 0x800b,0x8039 |
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -040034 * | AER/EEH | 0x9011 | |
Arun Easie02587d2011-08-16 11:29:23 -070035 * | Virtual Port | 0xa007 | |
Chad Dupuis7916bb92012-08-22 14:20:57 -040036 * | ISP82XX Specific | 0xb055 | 0xb024 |
Giridhar Malavali6246b8a2012-02-09 11:15:34 -080037 * | MultiQ | 0xc00c | |
38 * | Misc | 0xd010 | |
Nicholas Bellinger2d70c102012-05-15 14:34:28 -040039 * | Target Mode | 0xe06f | |
40 * | Target Mode Management | 0xf071 | |
41 * | Target Mode Task Management | 0x1000b | |
Arun Easie02587d2011-08-16 11:29:23 -070042 * ----------------------------------------------------------------------
Saurav Kashyap3ce88662011-07-14 12:00:12 -070043 */
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include "qla_def.h"
46
47#include <linux/delay.h>
48
Saurav Kashyap3ce88662011-07-14 12:00:12 -070049static uint32_t ql_dbg_offset = 0x800;
50
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070051static inline void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080052qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070053{
54 fw_dump->fw_major_version = htonl(ha->fw_major_version);
55 fw_dump->fw_minor_version = htonl(ha->fw_minor_version);
56 fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version);
57 fw_dump->fw_attributes = htonl(ha->fw_attributes);
58
59 fw_dump->vendor = htonl(ha->pdev->vendor);
60 fw_dump->device = htonl(ha->pdev->device);
61 fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor);
62 fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device);
63}
64
65static inline void *
Anirban Chakraborty73208df2008-12-09 16:45:39 -080066qla2xxx_copy_queues(struct qla_hw_data *ha, void *ptr)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070067{
Anirban Chakraborty73208df2008-12-09 16:45:39 -080068 struct req_que *req = ha->req_q_map[0];
69 struct rsp_que *rsp = ha->rsp_q_map[0];
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070070 /* Request queue. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080071 memcpy(ptr, req->ring, req->length *
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070072 sizeof(request_t));
73
74 /* Response queue. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080075 ptr += req->length * sizeof(request_t);
76 memcpy(ptr, rsp->ring, rsp->length *
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070077 sizeof(response_t));
78
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080079 return ptr + (rsp->length * sizeof(response_t));
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070080}
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -070082static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080083qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
Andrew Vasquezc5722702008-04-24 15:21:22 -070084 uint32_t ram_dwords, void **nxt)
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -070085{
86 int rval;
Andrew Vasquezc5722702008-04-24 15:21:22 -070087 uint32_t cnt, stat, timer, dwords, idx;
88 uint16_t mb0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -070089 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
Andrew Vasquezc5722702008-04-24 15:21:22 -070090 dma_addr_t dump_dma = ha->gid_list_dma;
91 uint32_t *dump = (uint32_t *)ha->gid_list;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -070092
93 rval = QLA_SUCCESS;
Andrew Vasquezc5722702008-04-24 15:21:22 -070094 mb0 = 0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -070095
Andrew Vasquezc5722702008-04-24 15:21:22 -070096 WRT_REG_WORD(&reg->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -070097 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
98
Chad Dupuis642ef982012-02-09 11:15:57 -080099 dwords = qla2x00_gid_list_size(ha) / 4;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700100 for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS;
101 cnt += dwords, addr += dwords) {
102 if (cnt + dwords > ram_dwords)
103 dwords = ram_dwords - cnt;
104
105 WRT_REG_WORD(&reg->mailbox1, LSW(addr));
106 WRT_REG_WORD(&reg->mailbox8, MSW(addr));
107
108 WRT_REG_WORD(&reg->mailbox2, MSW(dump_dma));
109 WRT_REG_WORD(&reg->mailbox3, LSW(dump_dma));
110 WRT_REG_WORD(&reg->mailbox6, MSW(MSD(dump_dma)));
111 WRT_REG_WORD(&reg->mailbox7, LSW(MSD(dump_dma)));
112
113 WRT_REG_WORD(&reg->mailbox4, MSW(dwords));
114 WRT_REG_WORD(&reg->mailbox5, LSW(dwords));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700115 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
116
117 for (timer = 6000000; timer; timer--) {
118 /* Check for pending interrupts. */
119 stat = RD_REG_DWORD(&reg->host_status);
120 if (stat & HSRX_RISC_INT) {
121 stat &= 0xff;
122
123 if (stat == 0x1 || stat == 0x2 ||
124 stat == 0x10 || stat == 0x11) {
125 set_bit(MBX_INTERRUPT,
126 &ha->mbx_cmd_flags);
127
Andrew Vasquezc5722702008-04-24 15:21:22 -0700128 mb0 = RD_REG_WORD(&reg->mailbox0);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700129
130 WRT_REG_DWORD(&reg->hccr,
131 HCCRX_CLR_RISC_INT);
132 RD_REG_DWORD(&reg->hccr);
133 break;
134 }
135
136 /* Clear this intr; it wasn't a mailbox intr */
137 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
138 RD_REG_DWORD(&reg->hccr);
139 }
140 udelay(5);
141 }
142
143 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
Andrew Vasquezc5722702008-04-24 15:21:22 -0700144 rval = mb0 & MBS_MASK;
145 for (idx = 0; idx < dwords; idx++)
146 ram[cnt + idx] = swab32(dump[idx]);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700147 } else {
148 rval = QLA_FUNCTION_FAILED;
149 }
150 }
151
Andrew Vasquezc5722702008-04-24 15:21:22 -0700152 *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700153 return rval;
154}
155
Andrew Vasquezc5722702008-04-24 15:21:22 -0700156static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800157qla24xx_dump_memory(struct qla_hw_data *ha, uint32_t *code_ram,
Andrew Vasquezc5722702008-04-24 15:21:22 -0700158 uint32_t cram_size, void **nxt)
159{
160 int rval;
161
162 /* Code RAM. */
163 rval = qla24xx_dump_ram(ha, 0x20000, code_ram, cram_size / 4, nxt);
164 if (rval != QLA_SUCCESS)
165 return rval;
166
167 /* External Memory. */
168 return qla24xx_dump_ram(ha, 0x100000, *nxt,
169 ha->fw_memory_size - 0x100000 + 1, nxt);
170}
171
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700172static uint32_t *
173qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase,
174 uint32_t count, uint32_t *buf)
175{
176 uint32_t __iomem *dmp_reg;
177
178 WRT_REG_DWORD(&reg->iobase_addr, iobase);
179 dmp_reg = &reg->iobase_window;
180 while (count--)
181 *buf++ = htonl(RD_REG_DWORD(dmp_reg++));
182
183 return buf;
184}
185
186static inline int
187qla24xx_pause_risc(struct device_reg_24xx __iomem *reg)
188{
189 int rval = QLA_SUCCESS;
190 uint32_t cnt;
191
Andrew Vasquezc3b058a2007-09-20 14:07:38 -0700192 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
Andrew Vasquezaed10882009-06-03 09:55:26 -0700193 for (cnt = 30000;
194 ((RD_REG_DWORD(&reg->host_status) & HSRX_RISC_PAUSED) == 0) &&
Andrew Vasquezc3b058a2007-09-20 14:07:38 -0700195 rval == QLA_SUCCESS; cnt--) {
196 if (cnt)
197 udelay(100);
198 else
199 rval = QLA_FUNCTION_TIMEOUT;
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700200 }
201
202 return rval;
203}
204
205static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800206qla24xx_soft_reset(struct qla_hw_data *ha)
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700207{
208 int rval = QLA_SUCCESS;
209 uint32_t cnt;
210 uint16_t mb0, wd;
211 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
212
213 /* Reset RISC. */
214 WRT_REG_DWORD(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
215 for (cnt = 0; cnt < 30000; cnt++) {
216 if ((RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
217 break;
218
219 udelay(10);
220 }
221
222 WRT_REG_DWORD(&reg->ctrl_status,
223 CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
224 pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
225
226 udelay(100);
227 /* Wait for firmware to complete NVRAM accesses. */
228 mb0 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
229 for (cnt = 10000 ; cnt && mb0; cnt--) {
230 udelay(5);
231 mb0 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
232 barrier();
233 }
234
235 /* Wait for soft-reset to complete. */
236 for (cnt = 0; cnt < 30000; cnt++) {
237 if ((RD_REG_DWORD(&reg->ctrl_status) &
238 CSRX_ISP_SOFT_RESET) == 0)
239 break;
240
241 udelay(10);
242 }
243 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
244 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
245
246 for (cnt = 30000; RD_REG_WORD(&reg->mailbox0) != 0 &&
247 rval == QLA_SUCCESS; cnt--) {
248 if (cnt)
249 udelay(100);
250 else
251 rval = QLA_FUNCTION_TIMEOUT;
252 }
253
254 return rval;
255}
256
Andrew Vasquezc5722702008-04-24 15:21:22 -0700257static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800258qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram,
Andrew Vasqueze18e9632009-06-17 10:30:31 -0700259 uint32_t ram_words, void **nxt)
Andrew Vasquezc5722702008-04-24 15:21:22 -0700260{
261 int rval;
262 uint32_t cnt, stat, timer, words, idx;
263 uint16_t mb0;
264 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
265 dma_addr_t dump_dma = ha->gid_list_dma;
266 uint16_t *dump = (uint16_t *)ha->gid_list;
267
268 rval = QLA_SUCCESS;
269 mb0 = 0;
270
271 WRT_MAILBOX_REG(ha, reg, 0, MBC_DUMP_RISC_RAM_EXTENDED);
272 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
273
Chad Dupuis642ef982012-02-09 11:15:57 -0800274 words = qla2x00_gid_list_size(ha) / 2;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700275 for (cnt = 0; cnt < ram_words && rval == QLA_SUCCESS;
276 cnt += words, addr += words) {
277 if (cnt + words > ram_words)
278 words = ram_words - cnt;
279
280 WRT_MAILBOX_REG(ha, reg, 1, LSW(addr));
281 WRT_MAILBOX_REG(ha, reg, 8, MSW(addr));
282
283 WRT_MAILBOX_REG(ha, reg, 2, MSW(dump_dma));
284 WRT_MAILBOX_REG(ha, reg, 3, LSW(dump_dma));
285 WRT_MAILBOX_REG(ha, reg, 6, MSW(MSD(dump_dma)));
286 WRT_MAILBOX_REG(ha, reg, 7, LSW(MSD(dump_dma)));
287
288 WRT_MAILBOX_REG(ha, reg, 4, words);
289 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
290
291 for (timer = 6000000; timer; timer--) {
292 /* Check for pending interrupts. */
293 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
294 if (stat & HSR_RISC_INT) {
295 stat &= 0xff;
296
297 if (stat == 0x1 || stat == 0x2) {
298 set_bit(MBX_INTERRUPT,
299 &ha->mbx_cmd_flags);
300
301 mb0 = RD_MAILBOX_REG(ha, reg, 0);
302
303 /* Release mailbox registers. */
304 WRT_REG_WORD(&reg->semaphore, 0);
305 WRT_REG_WORD(&reg->hccr,
306 HCCR_CLR_RISC_INT);
307 RD_REG_WORD(&reg->hccr);
308 break;
309 } else if (stat == 0x10 || stat == 0x11) {
310 set_bit(MBX_INTERRUPT,
311 &ha->mbx_cmd_flags);
312
313 mb0 = RD_MAILBOX_REG(ha, reg, 0);
314
315 WRT_REG_WORD(&reg->hccr,
316 HCCR_CLR_RISC_INT);
317 RD_REG_WORD(&reg->hccr);
318 break;
319 }
320
321 /* clear this intr; it wasn't a mailbox intr */
322 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
323 RD_REG_WORD(&reg->hccr);
324 }
325 udelay(5);
326 }
327
328 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
329 rval = mb0 & MBS_MASK;
330 for (idx = 0; idx < words; idx++)
331 ram[cnt + idx] = swab16(dump[idx]);
332 } else {
333 rval = QLA_FUNCTION_FAILED;
334 }
335 }
336
337 *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL;
338 return rval;
339}
340
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700341static inline void
342qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count,
343 uint16_t *buf)
344{
345 uint16_t __iomem *dmp_reg = &reg->u.isp2300.fb_cmd;
346
347 while (count--)
348 *buf++ = htons(RD_REG_WORD(dmp_reg++));
349}
350
Andrew Vasquezbb99de62009-01-05 11:18:08 -0800351static inline void *
352qla24xx_copy_eft(struct qla_hw_data *ha, void *ptr)
353{
354 if (!ha->eft)
355 return ptr;
356
357 memcpy(ptr, ha->eft, ntohl(ha->fw_dump->eft_size));
358 return ptr + ntohl(ha->fw_dump->eft_size);
359}
360
361static inline void *
362qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
363{
364 uint32_t cnt;
365 uint32_t *iter_reg;
366 struct qla2xxx_fce_chain *fcec = ptr;
367
368 if (!ha->fce)
369 return ptr;
370
371 *last_chain = &fcec->type;
372 fcec->type = __constant_htonl(DUMP_CHAIN_FCE);
373 fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) +
374 fce_calc_size(ha->fce_bufs));
375 fcec->size = htonl(fce_calc_size(ha->fce_bufs));
376 fcec->addr_l = htonl(LSD(ha->fce_dma));
377 fcec->addr_h = htonl(MSD(ha->fce_dma));
378
379 iter_reg = fcec->eregs;
380 for (cnt = 0; cnt < 8; cnt++)
381 *iter_reg++ = htonl(ha->fce_mb[cnt]);
382
383 memcpy(iter_reg, ha->fce, ntohl(fcec->size));
384
Giridhar Malavali3cb0a672011-11-18 09:03:11 -0800385 return (char *)iter_reg + ntohl(fcec->size);
Andrew Vasquezbb99de62009-01-05 11:18:08 -0800386}
387
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800388static inline void *
Nicholas Bellinger2d70c102012-05-15 14:34:28 -0400389qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr,
390 uint32_t **last_chain)
391{
392 struct qla2xxx_mqueue_chain *q;
393 struct qla2xxx_mqueue_header *qh;
394 uint32_t num_queues;
395 int que;
396 struct {
397 int length;
398 void *ring;
399 } aq, *aqp;
400
401 if (!ha->tgt.atio_q_length)
402 return ptr;
403
404 num_queues = 1;
405 aqp = &aq;
406 aqp->length = ha->tgt.atio_q_length;
407 aqp->ring = ha->tgt.atio_ring;
408
409 for (que = 0; que < num_queues; que++) {
410 /* aqp = ha->atio_q_map[que]; */
411 q = ptr;
412 *last_chain = &q->type;
413 q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
414 q->chain_size = htonl(
415 sizeof(struct qla2xxx_mqueue_chain) +
416 sizeof(struct qla2xxx_mqueue_header) +
417 (aqp->length * sizeof(request_t)));
418 ptr += sizeof(struct qla2xxx_mqueue_chain);
419
420 /* Add header. */
421 qh = ptr;
422 qh->queue = __constant_htonl(TYPE_ATIO_QUEUE);
423 qh->number = htonl(que);
424 qh->size = htonl(aqp->length * sizeof(request_t));
425 ptr += sizeof(struct qla2xxx_mqueue_header);
426
427 /* Add data. */
428 memcpy(ptr, aqp->ring, aqp->length * sizeof(request_t));
429
430 ptr += aqp->length * sizeof(request_t);
431 }
432
433 return ptr;
434}
435
436static inline void *
Giridhar Malavali050c9bb2012-02-09 11:15:33 -0800437qla25xx_copy_mqueues(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
438{
439 struct qla2xxx_mqueue_chain *q;
440 struct qla2xxx_mqueue_header *qh;
441 struct req_que *req;
442 struct rsp_que *rsp;
443 int que;
444
445 if (!ha->mqenable)
446 return ptr;
447
448 /* Request queues */
449 for (que = 1; que < ha->max_req_queues; que++) {
450 req = ha->req_q_map[que];
451 if (!req)
452 break;
453
454 /* Add chain. */
455 q = ptr;
456 *last_chain = &q->type;
457 q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
458 q->chain_size = htonl(
459 sizeof(struct qla2xxx_mqueue_chain) +
460 sizeof(struct qla2xxx_mqueue_header) +
461 (req->length * sizeof(request_t)));
462 ptr += sizeof(struct qla2xxx_mqueue_chain);
463
464 /* Add header. */
465 qh = ptr;
466 qh->queue = __constant_htonl(TYPE_REQUEST_QUEUE);
467 qh->number = htonl(que);
468 qh->size = htonl(req->length * sizeof(request_t));
469 ptr += sizeof(struct qla2xxx_mqueue_header);
470
471 /* Add data. */
472 memcpy(ptr, req->ring, req->length * sizeof(request_t));
473 ptr += req->length * sizeof(request_t);
474 }
475
476 /* Response queues */
477 for (que = 1; que < ha->max_rsp_queues; que++) {
478 rsp = ha->rsp_q_map[que];
479 if (!rsp)
480 break;
481
482 /* Add chain. */
483 q = ptr;
484 *last_chain = &q->type;
485 q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
486 q->chain_size = htonl(
487 sizeof(struct qla2xxx_mqueue_chain) +
488 sizeof(struct qla2xxx_mqueue_header) +
489 (rsp->length * sizeof(response_t)));
490 ptr += sizeof(struct qla2xxx_mqueue_chain);
491
492 /* Add header. */
493 qh = ptr;
494 qh->queue = __constant_htonl(TYPE_RESPONSE_QUEUE);
495 qh->number = htonl(que);
496 qh->size = htonl(rsp->length * sizeof(response_t));
497 ptr += sizeof(struct qla2xxx_mqueue_header);
498
499 /* Add data. */
500 memcpy(ptr, rsp->ring, rsp->length * sizeof(response_t));
501 ptr += rsp->length * sizeof(response_t);
502 }
503
504 return ptr;
505}
506
507static inline void *
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800508qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
509{
510 uint32_t cnt, que_idx;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700511 uint8_t que_cnt;
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800512 struct qla2xxx_mq_chain *mq = ptr;
513 struct device_reg_25xxmq __iomem *reg;
514
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800515 if (!ha->mqenable || IS_QLA83XX(ha))
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800516 return ptr;
517
518 mq = ptr;
519 *last_chain = &mq->type;
520 mq->type = __constant_htonl(DUMP_CHAIN_MQ);
521 mq->chain_size = __constant_htonl(sizeof(struct qla2xxx_mq_chain));
522
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700523 que_cnt = ha->max_req_queues > ha->max_rsp_queues ?
524 ha->max_req_queues : ha->max_rsp_queues;
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800525 mq->count = htonl(que_cnt);
526 for (cnt = 0; cnt < que_cnt; cnt++) {
527 reg = (struct device_reg_25xxmq *) ((void *)
528 ha->mqiobase + cnt * QLA_QUE_PAGE);
529 que_idx = cnt * 4;
530 mq->qregs[que_idx] = htonl(RD_REG_DWORD(&reg->req_q_in));
531 mq->qregs[que_idx+1] = htonl(RD_REG_DWORD(&reg->req_q_out));
532 mq->qregs[que_idx+2] = htonl(RD_REG_DWORD(&reg->rsp_q_in));
533 mq->qregs[que_idx+3] = htonl(RD_REG_DWORD(&reg->rsp_q_out));
534 }
535
536 return ptr + sizeof(struct qla2xxx_mq_chain);
537}
538
Giridhar Malavali08de2842011-08-16 11:31:44 -0700539void
Andrew Vasquez3420d362009-10-13 15:16:45 -0700540qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
541{
542 struct qla_hw_data *ha = vha->hw;
543
544 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700545 ql_log(ql_log_warn, vha, 0xd000,
546 "Failed to dump firmware (%x).\n", rval);
Andrew Vasquez3420d362009-10-13 15:16:45 -0700547 ha->fw_dumped = 0;
548 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700549 ql_log(ql_log_info, vha, 0xd001,
Andrew Vasquez3420d362009-10-13 15:16:45 -0700550 "Firmware dump saved to temp buffer (%ld/%p).\n",
551 vha->host_no, ha->fw_dump);
552 ha->fw_dumped = 1;
553 qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
554 }
555}
556
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557/**
558 * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
559 * @ha: HA context
560 * @hardware_locked: Called with the hardware_lock
561 */
562void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800563qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564{
565 int rval;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700566 uint32_t cnt;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800567 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez3d716442005-07-06 10:30:26 -0700568 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 uint16_t __iomem *dmp_reg;
570 unsigned long flags;
571 struct qla2300_fw_dump *fw;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700572 void *nxt;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800573 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 flags = 0;
576
577 if (!hardware_locked)
578 spin_lock_irqsave(&ha->hardware_lock, flags);
579
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700580 if (!ha->fw_dump) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700581 ql_log(ql_log_warn, vha, 0xd002,
582 "No buffer available for dump.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 goto qla2300_fw_dump_failed;
584 }
585
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700586 if (ha->fw_dumped) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700587 ql_log(ql_log_warn, vha, 0xd003,
588 "Firmware has been previously dumped (%p) "
589 "-- ignoring request.\n",
590 ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 goto qla2300_fw_dump_failed;
592 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700593 fw = &ha->fw_dump->isp.isp23;
594 qla2xxx_prep_dump(ha, ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595
596 rval = QLA_SUCCESS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700597 fw->hccr = htons(RD_REG_WORD(&reg->hccr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
599 /* Pause RISC. */
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700600 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601 if (IS_QLA2300(ha)) {
602 for (cnt = 30000;
603 (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
604 rval == QLA_SUCCESS; cnt--) {
605 if (cnt)
606 udelay(100);
607 else
608 rval = QLA_FUNCTION_TIMEOUT;
609 }
610 } else {
611 RD_REG_WORD(&reg->hccr); /* PCI Posting. */
612 udelay(10);
613 }
614
615 if (rval == QLA_SUCCESS) {
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700616 dmp_reg = &reg->flash_address;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700617 for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700618 fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700620 dmp_reg = &reg->u.isp2300.req_q_in;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700621 for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700622 fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700624 dmp_reg = &reg->u.isp2300.mailbox0;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700625 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700626 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627
628 WRT_REG_WORD(&reg->ctrl_status, 0x40);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700629 qla2xxx_read_window(reg, 32, fw->resp_dma_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
631 WRT_REG_WORD(&reg->ctrl_status, 0x50);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700632 qla2xxx_read_window(reg, 48, fw->dma_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633
634 WRT_REG_WORD(&reg->ctrl_status, 0x00);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700635 dmp_reg = &reg->risc_hw;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700636 for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700637 fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700639 WRT_REG_WORD(&reg->pcr, 0x2000);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700640 qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700642 WRT_REG_WORD(&reg->pcr, 0x2200);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700643 qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700645 WRT_REG_WORD(&reg->pcr, 0x2400);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700646 qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700648 WRT_REG_WORD(&reg->pcr, 0x2600);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700649 qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700651 WRT_REG_WORD(&reg->pcr, 0x2800);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700652 qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700654 WRT_REG_WORD(&reg->pcr, 0x2A00);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700655 qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700657 WRT_REG_WORD(&reg->pcr, 0x2C00);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700658 qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700660 WRT_REG_WORD(&reg->pcr, 0x2E00);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700661 qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700663 WRT_REG_WORD(&reg->ctrl_status, 0x10);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700664 qla2xxx_read_window(reg, 64, fw->frame_buf_hdw_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700666 WRT_REG_WORD(&reg->ctrl_status, 0x20);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700667 qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700669 WRT_REG_WORD(&reg->ctrl_status, 0x30);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700670 qla2xxx_read_window(reg, 64, fw->fpm_b1_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671
672 /* Reset RISC. */
673 WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
674 for (cnt = 0; cnt < 30000; cnt++) {
675 if ((RD_REG_WORD(&reg->ctrl_status) &
676 CSR_ISP_SOFT_RESET) == 0)
677 break;
678
679 udelay(10);
680 }
681 }
682
683 if (!IS_QLA2300(ha)) {
684 for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
685 rval == QLA_SUCCESS; cnt--) {
686 if (cnt)
687 udelay(100);
688 else
689 rval = QLA_FUNCTION_TIMEOUT;
690 }
691 }
692
Andrew Vasquezc5722702008-04-24 15:21:22 -0700693 /* Get RISC SRAM. */
694 if (rval == QLA_SUCCESS)
695 rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram,
696 sizeof(fw->risc_ram) / 2, &nxt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697
Andrew Vasquezc5722702008-04-24 15:21:22 -0700698 /* Get stack SRAM. */
699 if (rval == QLA_SUCCESS)
700 rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram,
701 sizeof(fw->stack_ram) / 2, &nxt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702
Andrew Vasquezc5722702008-04-24 15:21:22 -0700703 /* Get data SRAM. */
704 if (rval == QLA_SUCCESS)
705 rval = qla2xxx_dump_ram(ha, 0x11000, fw->data_ram,
706 ha->fw_memory_size - 0x11000 + 1, &nxt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700708 if (rval == QLA_SUCCESS)
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800709 qla2xxx_copy_queues(ha, nxt);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700710
Andrew Vasquez3420d362009-10-13 15:16:45 -0700711 qla2xxx_dump_post_process(base_vha, rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712
713qla2300_fw_dump_failed:
714 if (!hardware_locked)
715 spin_unlock_irqrestore(&ha->hardware_lock, flags);
716}
717
718/**
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware.
720 * @ha: HA context
721 * @hardware_locked: Called with the hardware_lock
722 */
723void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800724qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725{
726 int rval;
727 uint32_t cnt, timer;
728 uint16_t risc_address;
729 uint16_t mb0, mb2;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800730 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez3d716442005-07-06 10:30:26 -0700731 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 uint16_t __iomem *dmp_reg;
733 unsigned long flags;
734 struct qla2100_fw_dump *fw;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800735 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736
737 risc_address = 0;
738 mb0 = mb2 = 0;
739 flags = 0;
740
741 if (!hardware_locked)
742 spin_lock_irqsave(&ha->hardware_lock, flags);
743
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700744 if (!ha->fw_dump) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700745 ql_log(ql_log_warn, vha, 0xd004,
746 "No buffer available for dump.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 goto qla2100_fw_dump_failed;
748 }
749
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700750 if (ha->fw_dumped) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700751 ql_log(ql_log_warn, vha, 0xd005,
752 "Firmware has been previously dumped (%p) "
753 "-- ignoring request.\n",
754 ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 goto qla2100_fw_dump_failed;
756 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700757 fw = &ha->fw_dump->isp.isp21;
758 qla2xxx_prep_dump(ha, ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759
760 rval = QLA_SUCCESS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700761 fw->hccr = htons(RD_REG_WORD(&reg->hccr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762
763 /* Pause RISC. */
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700764 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 for (cnt = 30000; (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
766 rval == QLA_SUCCESS; cnt--) {
767 if (cnt)
768 udelay(100);
769 else
770 rval = QLA_FUNCTION_TIMEOUT;
771 }
772 if (rval == QLA_SUCCESS) {
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700773 dmp_reg = &reg->flash_address;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700774 for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700775 fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700777 dmp_reg = &reg->u.isp2100.mailbox0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700779 if (cnt == 8)
780 dmp_reg = &reg->u_end.isp2200.mailbox8;
781
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700782 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 }
784
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700785 dmp_reg = &reg->u.isp2100.unused_2[0];
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700786 for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700787 fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788
789 WRT_REG_WORD(&reg->ctrl_status, 0x00);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700790 dmp_reg = &reg->risc_hw;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700791 for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700792 fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700794 WRT_REG_WORD(&reg->pcr, 0x2000);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700795 qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700797 WRT_REG_WORD(&reg->pcr, 0x2100);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700798 qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700800 WRT_REG_WORD(&reg->pcr, 0x2200);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700801 qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700803 WRT_REG_WORD(&reg->pcr, 0x2300);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700804 qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700806 WRT_REG_WORD(&reg->pcr, 0x2400);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700807 qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700809 WRT_REG_WORD(&reg->pcr, 0x2500);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700810 qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700812 WRT_REG_WORD(&reg->pcr, 0x2600);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700813 qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700815 WRT_REG_WORD(&reg->pcr, 0x2700);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700816 qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700818 WRT_REG_WORD(&reg->ctrl_status, 0x10);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700819 qla2xxx_read_window(reg, 16, fw->frame_buf_hdw_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700821 WRT_REG_WORD(&reg->ctrl_status, 0x20);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700822 qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700824 WRT_REG_WORD(&reg->ctrl_status, 0x30);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700825 qla2xxx_read_window(reg, 64, fw->fpm_b1_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826
827 /* Reset the ISP. */
828 WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
829 }
830
831 for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
832 rval == QLA_SUCCESS; cnt--) {
833 if (cnt)
834 udelay(100);
835 else
836 rval = QLA_FUNCTION_TIMEOUT;
837 }
838
839 /* Pause RISC. */
840 if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) &&
841 (RD_REG_WORD(&reg->mctr) & (BIT_1 | BIT_0)) != 0))) {
842
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700843 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 for (cnt = 30000;
845 (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
846 rval == QLA_SUCCESS; cnt--) {
847 if (cnt)
848 udelay(100);
849 else
850 rval = QLA_FUNCTION_TIMEOUT;
851 }
852 if (rval == QLA_SUCCESS) {
853 /* Set memory configuration and timing. */
854 if (IS_QLA2100(ha))
855 WRT_REG_WORD(&reg->mctr, 0xf1);
856 else
857 WRT_REG_WORD(&reg->mctr, 0xf2);
858 RD_REG_WORD(&reg->mctr); /* PCI Posting. */
859
860 /* Release RISC. */
861 WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
862 }
863 }
864
865 if (rval == QLA_SUCCESS) {
866 /* Get RISC SRAM. */
867 risc_address = 0x1000;
868 WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
869 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
870 }
871 for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;
872 cnt++, risc_address++) {
873 WRT_MAILBOX_REG(ha, reg, 1, risc_address);
874 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
875
876 for (timer = 6000000; timer != 0; timer--) {
877 /* Check for pending interrupts. */
878 if (RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) {
879 if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
880 set_bit(MBX_INTERRUPT,
881 &ha->mbx_cmd_flags);
882
883 mb0 = RD_MAILBOX_REG(ha, reg, 0);
884 mb2 = RD_MAILBOX_REG(ha, reg, 2);
885
886 WRT_REG_WORD(&reg->semaphore, 0);
887 WRT_REG_WORD(&reg->hccr,
888 HCCR_CLR_RISC_INT);
889 RD_REG_WORD(&reg->hccr);
890 break;
891 }
892 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
893 RD_REG_WORD(&reg->hccr);
894 }
895 udelay(5);
896 }
897
898 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
899 rval = mb0 & MBS_MASK;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700900 fw->risc_ram[cnt] = htons(mb2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 } else {
902 rval = QLA_FUNCTION_FAILED;
903 }
904 }
905
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700906 if (rval == QLA_SUCCESS)
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800907 qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700908
Andrew Vasquez3420d362009-10-13 15:16:45 -0700909 qla2xxx_dump_post_process(base_vha, rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910
911qla2100_fw_dump_failed:
912 if (!hardware_locked)
913 spin_unlock_irqrestore(&ha->hardware_lock, flags);
914}
915
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700916void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800917qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700918{
919 int rval;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700920 uint32_t cnt;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700921 uint32_t risc_address;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800922 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700923 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
924 uint32_t __iomem *dmp_reg;
925 uint32_t *iter_reg;
926 uint16_t __iomem *mbx_reg;
927 unsigned long flags;
928 struct qla24xx_fw_dump *fw;
929 uint32_t ext_mem_cnt;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700930 void *nxt;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -0400931 void *nxt_chain;
932 uint32_t *last_chain = NULL;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800933 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700934
Giridhar Malavalia9083012010-04-12 17:59:55 -0700935 if (IS_QLA82XX(ha))
936 return;
937
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700938 risc_address = ext_mem_cnt = 0;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700939 flags = 0;
940
941 if (!hardware_locked)
942 spin_lock_irqsave(&ha->hardware_lock, flags);
943
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700944 if (!ha->fw_dump) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700945 ql_log(ql_log_warn, vha, 0xd006,
946 "No buffer available for dump.\n");
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700947 goto qla24xx_fw_dump_failed;
948 }
949
950 if (ha->fw_dumped) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700951 ql_log(ql_log_warn, vha, 0xd007,
952 "Firmware has been previously dumped (%p) "
953 "-- ignoring request.\n",
954 ha->fw_dump);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700955 goto qla24xx_fw_dump_failed;
956 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700957 fw = &ha->fw_dump->isp.isp24;
958 qla2xxx_prep_dump(ha, ha->fw_dump);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700959
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700960 fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700961
962 /* Pause RISC. */
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700963 rval = qla24xx_pause_risc(reg);
964 if (rval != QLA_SUCCESS)
965 goto qla24xx_fw_dump_failed_0;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700966
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700967 /* Host interface registers. */
968 dmp_reg = &reg->flash_addr;
969 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
970 fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700971
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700972 /* Disable interrupts. */
973 WRT_REG_DWORD(&reg->ictrl, 0);
974 RD_REG_DWORD(&reg->ictrl);
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800975
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700976 /* Shadow registers. */
977 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
978 RD_REG_DWORD(&reg->iobase_addr);
979 WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
980 fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800981
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700982 WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
983 fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800984
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700985 WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
986 fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800987
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700988 WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
989 fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800990
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700991 WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
992 fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800993
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700994 WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
995 fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800996
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700997 WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
998 fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800999
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001000 /* Mailbox registers. */
1001 mbx_reg = &reg->mailbox0;
1002 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
1003 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001004
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001005 /* Transfer sequence registers. */
1006 iter_reg = fw->xseq_gp_reg;
1007 iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1008 iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1009 iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1010 iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1011 iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1012 iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1013 iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1014 qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001015
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001016 qla24xx_read_window(reg, 0xBFE0, 16, fw->xseq_0_reg);
1017 qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001018
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001019 /* Receive sequence registers. */
1020 iter_reg = fw->rseq_gp_reg;
1021 iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1022 iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1023 iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1024 iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1025 iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1026 iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1027 iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1028 qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001029
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001030 qla24xx_read_window(reg, 0xFFD0, 16, fw->rseq_0_reg);
1031 qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1032 qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001033
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001034 /* Command DMA registers. */
1035 qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001036
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001037 /* Queues. */
1038 iter_reg = fw->req0_dma_reg;
1039 iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1040 dmp_reg = &reg->iobase_q;
1041 for (cnt = 0; cnt < 7; cnt++)
1042 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001043
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001044 iter_reg = fw->resp0_dma_reg;
1045 iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1046 dmp_reg = &reg->iobase_q;
1047 for (cnt = 0; cnt < 7; cnt++)
1048 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001049
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001050 iter_reg = fw->req1_dma_reg;
1051 iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1052 dmp_reg = &reg->iobase_q;
1053 for (cnt = 0; cnt < 7; cnt++)
1054 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001055
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001056 /* Transmit DMA registers. */
1057 iter_reg = fw->xmt0_dma_reg;
1058 iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1059 qla24xx_read_window(reg, 0x7610, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001060
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001061 iter_reg = fw->xmt1_dma_reg;
1062 iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1063 qla24xx_read_window(reg, 0x7630, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001064
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001065 iter_reg = fw->xmt2_dma_reg;
1066 iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1067 qla24xx_read_window(reg, 0x7650, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001068
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001069 iter_reg = fw->xmt3_dma_reg;
1070 iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1071 qla24xx_read_window(reg, 0x7670, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001072
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001073 iter_reg = fw->xmt4_dma_reg;
1074 iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1075 qla24xx_read_window(reg, 0x7690, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001076
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001077 qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001078
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001079 /* Receive DMA registers. */
1080 iter_reg = fw->rcvt0_data_dma_reg;
1081 iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1082 qla24xx_read_window(reg, 0x7710, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001083
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001084 iter_reg = fw->rcvt1_data_dma_reg;
1085 iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1086 qla24xx_read_window(reg, 0x7730, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001087
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001088 /* RISC registers. */
1089 iter_reg = fw->risc_gp_reg;
1090 iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1091 iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1092 iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1093 iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1094 iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1095 iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1096 iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1097 qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001098
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001099 /* Local memory controller registers. */
1100 iter_reg = fw->lmc_reg;
1101 iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1102 iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1103 iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1104 iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1105 iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1106 iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1107 qla24xx_read_window(reg, 0x3060, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001108
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001109 /* Fibre Protocol Module registers. */
1110 iter_reg = fw->fpm_hdw_reg;
1111 iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1112 iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1113 iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1114 iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1115 iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1116 iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1117 iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1118 iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1119 iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1120 iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1121 iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1122 qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001123
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001124 /* Frame Buffer registers. */
1125 iter_reg = fw->fb_hdw_reg;
1126 iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1127 iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1128 iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1129 iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1130 iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1131 iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1132 iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1133 iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1134 iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1135 iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1136 qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001137
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001138 rval = qla24xx_soft_reset(ha);
1139 if (rval != QLA_SUCCESS)
1140 goto qla24xx_fw_dump_failed_0;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001141
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001142 rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
Andrew Vasquezc5722702008-04-24 15:21:22 -07001143 &nxt);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001144 if (rval != QLA_SUCCESS)
1145 goto qla24xx_fw_dump_failed_0;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001146
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001147 nxt = qla2xxx_copy_queues(ha, nxt);
Andrew Vasquezbb99de62009-01-05 11:18:08 -08001148
1149 qla24xx_copy_eft(ha, nxt);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001150
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001151 nxt_chain = (void *)ha->fw_dump + ha->chain_offset;
1152 nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
1153 if (last_chain) {
1154 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
1155 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
1156 }
1157
1158 /* Adjust valid length. */
1159 ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1160
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001161qla24xx_fw_dump_failed_0:
Andrew Vasquez3420d362009-10-13 15:16:45 -07001162 qla2xxx_dump_post_process(base_vha, rval);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001163
1164qla24xx_fw_dump_failed:
1165 if (!hardware_locked)
1166 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1167}
1168
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001169void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001170qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001171{
1172 int rval;
1173 uint32_t cnt;
1174 uint32_t risc_address;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001175 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001176 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1177 uint32_t __iomem *dmp_reg;
1178 uint32_t *iter_reg;
1179 uint16_t __iomem *mbx_reg;
1180 unsigned long flags;
1181 struct qla25xx_fw_dump *fw;
1182 uint32_t ext_mem_cnt;
Andrew Vasquezd63ab532009-01-05 11:18:09 -08001183 void *nxt, *nxt_chain;
Andrew Vasquezbb99de62009-01-05 11:18:08 -08001184 uint32_t *last_chain = NULL;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001185 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001186
1187 risc_address = ext_mem_cnt = 0;
1188 flags = 0;
1189
1190 if (!hardware_locked)
1191 spin_lock_irqsave(&ha->hardware_lock, flags);
1192
1193 if (!ha->fw_dump) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001194 ql_log(ql_log_warn, vha, 0xd008,
1195 "No buffer available for dump.\n");
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001196 goto qla25xx_fw_dump_failed;
1197 }
1198
1199 if (ha->fw_dumped) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001200 ql_log(ql_log_warn, vha, 0xd009,
1201 "Firmware has been previously dumped (%p) "
1202 "-- ignoring request.\n",
1203 ha->fw_dump);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001204 goto qla25xx_fw_dump_failed;
1205 }
1206 fw = &ha->fw_dump->isp.isp25;
1207 qla2xxx_prep_dump(ha, ha->fw_dump);
Andrew Vasquezb5836922007-09-20 14:07:39 -07001208 ha->fw_dump->version = __constant_htonl(2);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001209
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001210 fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
1211
1212 /* Pause RISC. */
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001213 rval = qla24xx_pause_risc(reg);
1214 if (rval != QLA_SUCCESS)
1215 goto qla25xx_fw_dump_failed_0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001216
Andrew Vasquezb5836922007-09-20 14:07:39 -07001217 /* Host/Risc registers. */
1218 iter_reg = fw->host_risc_reg;
1219 iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
1220 qla24xx_read_window(reg, 0x7010, 16, iter_reg);
1221
1222 /* PCIe registers. */
1223 WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
1224 RD_REG_DWORD(&reg->iobase_addr);
1225 WRT_REG_DWORD(&reg->iobase_window, 0x01);
1226 dmp_reg = &reg->iobase_c4;
1227 fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++));
1228 fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
1229 fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
1230 fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001231
Andrew Vasquezb5836922007-09-20 14:07:39 -07001232 WRT_REG_DWORD(&reg->iobase_window, 0x00);
1233 RD_REG_DWORD(&reg->iobase_window);
1234
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001235 /* Host interface registers. */
1236 dmp_reg = &reg->flash_addr;
1237 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
1238 fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001239
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001240 /* Disable interrupts. */
1241 WRT_REG_DWORD(&reg->ictrl, 0);
1242 RD_REG_DWORD(&reg->ictrl);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001243
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001244 /* Shadow registers. */
1245 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1246 RD_REG_DWORD(&reg->iobase_addr);
1247 WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
1248 fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001249
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001250 WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
1251 fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001252
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001253 WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
1254 fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001255
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001256 WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
1257 fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001258
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001259 WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
1260 fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001261
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001262 WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
1263 fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001264
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001265 WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
1266 fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001267
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001268 WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
1269 fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001270
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001271 WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
1272 fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001273
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001274 WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
1275 fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001276
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001277 WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
1278 fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001279
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001280 /* RISC I/O register. */
1281 WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
1282 fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001283
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001284 /* Mailbox registers. */
1285 mbx_reg = &reg->mailbox0;
1286 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
1287 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001288
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001289 /* Transfer sequence registers. */
1290 iter_reg = fw->xseq_gp_reg;
1291 iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1292 iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1293 iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1294 iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1295 iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1296 iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1297 iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1298 qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001299
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001300 iter_reg = fw->xseq_0_reg;
1301 iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
1302 iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
1303 qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001304
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001305 qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001306
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001307 /* Receive sequence registers. */
1308 iter_reg = fw->rseq_gp_reg;
1309 iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1310 iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1311 iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1312 iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1313 iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1314 iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1315 iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1316 qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001317
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001318 iter_reg = fw->rseq_0_reg;
1319 iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
1320 qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001321
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001322 qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1323 qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001324
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001325 /* Auxiliary sequence registers. */
1326 iter_reg = fw->aseq_gp_reg;
1327 iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
1328 iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
1329 iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
1330 iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
1331 iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
1332 iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
1333 iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
1334 qla24xx_read_window(reg, 0xB070, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001335
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001336 iter_reg = fw->aseq_0_reg;
1337 iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
1338 qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001339
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001340 qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
1341 qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001342
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001343 /* Command DMA registers. */
1344 qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001345
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001346 /* Queues. */
1347 iter_reg = fw->req0_dma_reg;
1348 iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1349 dmp_reg = &reg->iobase_q;
1350 for (cnt = 0; cnt < 7; cnt++)
1351 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001352
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001353 iter_reg = fw->resp0_dma_reg;
1354 iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1355 dmp_reg = &reg->iobase_q;
1356 for (cnt = 0; cnt < 7; cnt++)
1357 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001358
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001359 iter_reg = fw->req1_dma_reg;
1360 iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1361 dmp_reg = &reg->iobase_q;
1362 for (cnt = 0; cnt < 7; cnt++)
1363 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001364
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001365 /* Transmit DMA registers. */
1366 iter_reg = fw->xmt0_dma_reg;
1367 iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1368 qla24xx_read_window(reg, 0x7610, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001369
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001370 iter_reg = fw->xmt1_dma_reg;
1371 iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1372 qla24xx_read_window(reg, 0x7630, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001373
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001374 iter_reg = fw->xmt2_dma_reg;
1375 iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1376 qla24xx_read_window(reg, 0x7650, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001377
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001378 iter_reg = fw->xmt3_dma_reg;
1379 iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1380 qla24xx_read_window(reg, 0x7670, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001381
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001382 iter_reg = fw->xmt4_dma_reg;
1383 iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1384 qla24xx_read_window(reg, 0x7690, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001385
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001386 qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001387
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001388 /* Receive DMA registers. */
1389 iter_reg = fw->rcvt0_data_dma_reg;
1390 iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1391 qla24xx_read_window(reg, 0x7710, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001392
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001393 iter_reg = fw->rcvt1_data_dma_reg;
1394 iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1395 qla24xx_read_window(reg, 0x7730, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001396
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001397 /* RISC registers. */
1398 iter_reg = fw->risc_gp_reg;
1399 iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1400 iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1401 iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1402 iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1403 iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1404 iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1405 iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1406 qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001407
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001408 /* Local memory controller registers. */
1409 iter_reg = fw->lmc_reg;
1410 iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1411 iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1412 iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1413 iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1414 iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1415 iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1416 iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
1417 qla24xx_read_window(reg, 0x3070, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001418
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001419 /* Fibre Protocol Module registers. */
1420 iter_reg = fw->fpm_hdw_reg;
1421 iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1422 iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1423 iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1424 iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1425 iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1426 iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1427 iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1428 iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1429 iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1430 iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1431 iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1432 qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001433
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001434 /* Frame Buffer registers. */
1435 iter_reg = fw->fb_hdw_reg;
1436 iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1437 iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1438 iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1439 iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1440 iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1441 iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1442 iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1443 iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1444 iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1445 iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1446 iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
1447 qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001448
Andrew Vasquezd63ab532009-01-05 11:18:09 -08001449 /* Multi queue registers */
1450 nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
1451 &last_chain);
1452
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001453 rval = qla24xx_soft_reset(ha);
1454 if (rval != QLA_SUCCESS)
1455 goto qla25xx_fw_dump_failed_0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001456
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001457 rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
Andrew Vasquezc5722702008-04-24 15:21:22 -07001458 &nxt);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001459 if (rval != QLA_SUCCESS)
1460 goto qla25xx_fw_dump_failed_0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001461
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001462 nxt = qla2xxx_copy_queues(ha, nxt);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001463
Andrew Vasquezbb99de62009-01-05 11:18:08 -08001464 nxt = qla24xx_copy_eft(ha, nxt);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08001465
Andrew Vasquezd63ab532009-01-05 11:18:09 -08001466 /* Chain entries -- started with MQ. */
Giridhar Malavali050c9bb2012-02-09 11:15:33 -08001467 nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
1468 nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001469 nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
Andrew Vasquezbb99de62009-01-05 11:18:08 -08001470 if (last_chain) {
1471 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
1472 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
1473 }
Andrew Vasquezdf613b92008-01-17 09:02:17 -08001474
Giridhar Malavali050c9bb2012-02-09 11:15:33 -08001475 /* Adjust valid length. */
1476 ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1477
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001478qla25xx_fw_dump_failed_0:
Andrew Vasquez3420d362009-10-13 15:16:45 -07001479 qla2xxx_dump_post_process(base_vha, rval);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001480
1481qla25xx_fw_dump_failed:
1482 if (!hardware_locked)
1483 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1484}
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001485
1486void
1487qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
1488{
1489 int rval;
1490 uint32_t cnt;
1491 uint32_t risc_address;
1492 struct qla_hw_data *ha = vha->hw;
1493 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1494 uint32_t __iomem *dmp_reg;
1495 uint32_t *iter_reg;
1496 uint16_t __iomem *mbx_reg;
1497 unsigned long flags;
1498 struct qla81xx_fw_dump *fw;
1499 uint32_t ext_mem_cnt;
1500 void *nxt, *nxt_chain;
1501 uint32_t *last_chain = NULL;
1502 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
1503
1504 risc_address = ext_mem_cnt = 0;
1505 flags = 0;
1506
1507 if (!hardware_locked)
1508 spin_lock_irqsave(&ha->hardware_lock, flags);
1509
1510 if (!ha->fw_dump) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001511 ql_log(ql_log_warn, vha, 0xd00a,
1512 "No buffer available for dump.\n");
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001513 goto qla81xx_fw_dump_failed;
1514 }
1515
1516 if (ha->fw_dumped) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001517 ql_log(ql_log_warn, vha, 0xd00b,
1518 "Firmware has been previously dumped (%p) "
1519 "-- ignoring request.\n",
1520 ha->fw_dump);
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001521 goto qla81xx_fw_dump_failed;
1522 }
1523 fw = &ha->fw_dump->isp.isp81;
1524 qla2xxx_prep_dump(ha, ha->fw_dump);
1525
1526 fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
1527
1528 /* Pause RISC. */
1529 rval = qla24xx_pause_risc(reg);
1530 if (rval != QLA_SUCCESS)
1531 goto qla81xx_fw_dump_failed_0;
1532
1533 /* Host/Risc registers. */
1534 iter_reg = fw->host_risc_reg;
1535 iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
1536 qla24xx_read_window(reg, 0x7010, 16, iter_reg);
1537
1538 /* PCIe registers. */
1539 WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
1540 RD_REG_DWORD(&reg->iobase_addr);
1541 WRT_REG_DWORD(&reg->iobase_window, 0x01);
1542 dmp_reg = &reg->iobase_c4;
1543 fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++));
1544 fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
1545 fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
1546 fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
1547
1548 WRT_REG_DWORD(&reg->iobase_window, 0x00);
1549 RD_REG_DWORD(&reg->iobase_window);
1550
1551 /* Host interface registers. */
1552 dmp_reg = &reg->flash_addr;
1553 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
1554 fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
1555
1556 /* Disable interrupts. */
1557 WRT_REG_DWORD(&reg->ictrl, 0);
1558 RD_REG_DWORD(&reg->ictrl);
1559
1560 /* Shadow registers. */
1561 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1562 RD_REG_DWORD(&reg->iobase_addr);
1563 WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
1564 fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1565
1566 WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
1567 fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1568
1569 WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
1570 fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1571
1572 WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
1573 fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1574
1575 WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
1576 fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1577
1578 WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
1579 fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1580
1581 WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
1582 fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1583
1584 WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
1585 fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1586
1587 WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
1588 fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1589
1590 WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
1591 fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1592
1593 WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
1594 fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1595
1596 /* RISC I/O register. */
1597 WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
1598 fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
1599
1600 /* Mailbox registers. */
1601 mbx_reg = &reg->mailbox0;
1602 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
1603 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
1604
1605 /* Transfer sequence registers. */
1606 iter_reg = fw->xseq_gp_reg;
1607 iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1608 iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1609 iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1610 iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1611 iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1612 iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1613 iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1614 qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
1615
1616 iter_reg = fw->xseq_0_reg;
1617 iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
1618 iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
1619 qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
1620
1621 qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
1622
1623 /* Receive sequence registers. */
1624 iter_reg = fw->rseq_gp_reg;
1625 iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1626 iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1627 iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1628 iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1629 iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1630 iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1631 iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1632 qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
1633
1634 iter_reg = fw->rseq_0_reg;
1635 iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
1636 qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
1637
1638 qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1639 qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
1640
1641 /* Auxiliary sequence registers. */
1642 iter_reg = fw->aseq_gp_reg;
1643 iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
1644 iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
1645 iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
1646 iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
1647 iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
1648 iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
1649 iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
1650 qla24xx_read_window(reg, 0xB070, 16, iter_reg);
1651
1652 iter_reg = fw->aseq_0_reg;
1653 iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
1654 qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
1655
1656 qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
1657 qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
1658
1659 /* Command DMA registers. */
1660 qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
1661
1662 /* Queues. */
1663 iter_reg = fw->req0_dma_reg;
1664 iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1665 dmp_reg = &reg->iobase_q;
1666 for (cnt = 0; cnt < 7; cnt++)
1667 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
1668
1669 iter_reg = fw->resp0_dma_reg;
1670 iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1671 dmp_reg = &reg->iobase_q;
1672 for (cnt = 0; cnt < 7; cnt++)
1673 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
1674
1675 iter_reg = fw->req1_dma_reg;
1676 iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1677 dmp_reg = &reg->iobase_q;
1678 for (cnt = 0; cnt < 7; cnt++)
1679 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
1680
1681 /* Transmit DMA registers. */
1682 iter_reg = fw->xmt0_dma_reg;
1683 iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1684 qla24xx_read_window(reg, 0x7610, 16, iter_reg);
1685
1686 iter_reg = fw->xmt1_dma_reg;
1687 iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1688 qla24xx_read_window(reg, 0x7630, 16, iter_reg);
1689
1690 iter_reg = fw->xmt2_dma_reg;
1691 iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1692 qla24xx_read_window(reg, 0x7650, 16, iter_reg);
1693
1694 iter_reg = fw->xmt3_dma_reg;
1695 iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1696 qla24xx_read_window(reg, 0x7670, 16, iter_reg);
1697
1698 iter_reg = fw->xmt4_dma_reg;
1699 iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1700 qla24xx_read_window(reg, 0x7690, 16, iter_reg);
1701
1702 qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
1703
1704 /* Receive DMA registers. */
1705 iter_reg = fw->rcvt0_data_dma_reg;
1706 iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1707 qla24xx_read_window(reg, 0x7710, 16, iter_reg);
1708
1709 iter_reg = fw->rcvt1_data_dma_reg;
1710 iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1711 qla24xx_read_window(reg, 0x7730, 16, iter_reg);
1712
1713 /* RISC registers. */
1714 iter_reg = fw->risc_gp_reg;
1715 iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1716 iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1717 iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1718 iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1719 iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1720 iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1721 iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1722 qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
1723
1724 /* Local memory controller registers. */
1725 iter_reg = fw->lmc_reg;
1726 iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1727 iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1728 iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1729 iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1730 iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1731 iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1732 iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
1733 qla24xx_read_window(reg, 0x3070, 16, iter_reg);
1734
1735 /* Fibre Protocol Module registers. */
1736 iter_reg = fw->fpm_hdw_reg;
1737 iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1738 iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1739 iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1740 iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1741 iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1742 iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1743 iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1744 iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1745 iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1746 iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1747 iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1748 iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
1749 iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
1750 qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
1751
1752 /* Frame Buffer registers. */
1753 iter_reg = fw->fb_hdw_reg;
1754 iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1755 iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1756 iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1757 iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1758 iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1759 iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1760 iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1761 iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1762 iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1763 iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1764 iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
1765 iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
1766 qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
1767
1768 /* Multi queue registers */
1769 nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
1770 &last_chain);
1771
1772 rval = qla24xx_soft_reset(ha);
1773 if (rval != QLA_SUCCESS)
1774 goto qla81xx_fw_dump_failed_0;
1775
1776 rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
1777 &nxt);
1778 if (rval != QLA_SUCCESS)
1779 goto qla81xx_fw_dump_failed_0;
1780
1781 nxt = qla2xxx_copy_queues(ha, nxt);
1782
1783 nxt = qla24xx_copy_eft(ha, nxt);
1784
1785 /* Chain entries -- started with MQ. */
Giridhar Malavali050c9bb2012-02-09 11:15:33 -08001786 nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
1787 nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001788 nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001789 if (last_chain) {
1790 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
1791 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
1792 }
1793
Giridhar Malavali050c9bb2012-02-09 11:15:33 -08001794 /* Adjust valid length. */
1795 ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1796
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001797qla81xx_fw_dump_failed_0:
Andrew Vasquez3420d362009-10-13 15:16:45 -07001798 qla2xxx_dump_post_process(base_vha, rval);
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001799
1800qla81xx_fw_dump_failed:
1801 if (!hardware_locked)
1802 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1803}
1804
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001805void
1806qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
1807{
1808 int rval;
1809 uint32_t cnt, reg_data;
1810 uint32_t risc_address;
1811 struct qla_hw_data *ha = vha->hw;
1812 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1813 uint32_t __iomem *dmp_reg;
1814 uint32_t *iter_reg;
1815 uint16_t __iomem *mbx_reg;
1816 unsigned long flags;
1817 struct qla83xx_fw_dump *fw;
1818 uint32_t ext_mem_cnt;
1819 void *nxt, *nxt_chain;
1820 uint32_t *last_chain = NULL;
1821 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
1822
1823 risc_address = ext_mem_cnt = 0;
1824 flags = 0;
1825
1826 if (!hardware_locked)
1827 spin_lock_irqsave(&ha->hardware_lock, flags);
1828
1829 if (!ha->fw_dump) {
1830 ql_log(ql_log_warn, vha, 0xd00c,
1831 "No buffer available for dump!!!\n");
1832 goto qla83xx_fw_dump_failed;
1833 }
1834
1835 if (ha->fw_dumped) {
1836 ql_log(ql_log_warn, vha, 0xd00d,
1837 "Firmware has been previously dumped (%p) -- ignoring "
1838 "request...\n", ha->fw_dump);
1839 goto qla83xx_fw_dump_failed;
1840 }
1841 fw = &ha->fw_dump->isp.isp83;
1842 qla2xxx_prep_dump(ha, ha->fw_dump);
1843
1844 fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
1845
1846 /* Pause RISC. */
1847 rval = qla24xx_pause_risc(reg);
1848 if (rval != QLA_SUCCESS)
1849 goto qla83xx_fw_dump_failed_0;
1850
1851 WRT_REG_DWORD(&reg->iobase_addr, 0x6000);
1852 dmp_reg = &reg->iobase_window;
1853 reg_data = RD_REG_DWORD(dmp_reg);
1854 WRT_REG_DWORD(dmp_reg, 0);
1855
1856 dmp_reg = &reg->unused_4_1[0];
1857 reg_data = RD_REG_DWORD(dmp_reg);
1858 WRT_REG_DWORD(dmp_reg, 0);
1859
1860 WRT_REG_DWORD(&reg->iobase_addr, 0x6010);
1861 dmp_reg = &reg->unused_4_1[2];
1862 reg_data = RD_REG_DWORD(dmp_reg);
1863 WRT_REG_DWORD(dmp_reg, 0);
1864
1865 /* select PCR and disable ecc checking and correction */
1866 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1867 RD_REG_DWORD(&reg->iobase_addr);
1868 WRT_REG_DWORD(&reg->iobase_select, 0x60000000); /* write to F0h = PCR */
1869
1870 /* Host/Risc registers. */
1871 iter_reg = fw->host_risc_reg;
1872 iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
1873 iter_reg = qla24xx_read_window(reg, 0x7010, 16, iter_reg);
1874 qla24xx_read_window(reg, 0x7040, 16, iter_reg);
1875
1876 /* PCIe registers. */
1877 WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
1878 RD_REG_DWORD(&reg->iobase_addr);
1879 WRT_REG_DWORD(&reg->iobase_window, 0x01);
1880 dmp_reg = &reg->iobase_c4;
1881 fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++));
1882 fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
1883 fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
1884 fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
1885
1886 WRT_REG_DWORD(&reg->iobase_window, 0x00);
1887 RD_REG_DWORD(&reg->iobase_window);
1888
1889 /* Host interface registers. */
1890 dmp_reg = &reg->flash_addr;
1891 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
1892 fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
1893
1894 /* Disable interrupts. */
1895 WRT_REG_DWORD(&reg->ictrl, 0);
1896 RD_REG_DWORD(&reg->ictrl);
1897
1898 /* Shadow registers. */
1899 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1900 RD_REG_DWORD(&reg->iobase_addr);
1901 WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
1902 fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1903
1904 WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
1905 fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1906
1907 WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
1908 fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1909
1910 WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
1911 fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1912
1913 WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
1914 fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1915
1916 WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
1917 fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1918
1919 WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
1920 fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1921
1922 WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
1923 fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1924
1925 WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
1926 fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1927
1928 WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
1929 fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1930
1931 WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
1932 fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1933
1934 /* RISC I/O register. */
1935 WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
1936 fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
1937
1938 /* Mailbox registers. */
1939 mbx_reg = &reg->mailbox0;
1940 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
1941 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
1942
1943 /* Transfer sequence registers. */
1944 iter_reg = fw->xseq_gp_reg;
1945 iter_reg = qla24xx_read_window(reg, 0xBE00, 16, iter_reg);
1946 iter_reg = qla24xx_read_window(reg, 0xBE10, 16, iter_reg);
1947 iter_reg = qla24xx_read_window(reg, 0xBE20, 16, iter_reg);
1948 iter_reg = qla24xx_read_window(reg, 0xBE30, 16, iter_reg);
1949 iter_reg = qla24xx_read_window(reg, 0xBE40, 16, iter_reg);
1950 iter_reg = qla24xx_read_window(reg, 0xBE50, 16, iter_reg);
1951 iter_reg = qla24xx_read_window(reg, 0xBE60, 16, iter_reg);
1952 iter_reg = qla24xx_read_window(reg, 0xBE70, 16, iter_reg);
1953 iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1954 iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1955 iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1956 iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1957 iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1958 iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1959 iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1960 qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
1961
1962 iter_reg = fw->xseq_0_reg;
1963 iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
1964 iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
1965 qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
1966
1967 qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
1968
1969 qla24xx_read_window(reg, 0xBEF0, 16, fw->xseq_2_reg);
1970
1971 /* Receive sequence registers. */
1972 iter_reg = fw->rseq_gp_reg;
1973 iter_reg = qla24xx_read_window(reg, 0xFE00, 16, iter_reg);
1974 iter_reg = qla24xx_read_window(reg, 0xFE10, 16, iter_reg);
1975 iter_reg = qla24xx_read_window(reg, 0xFE20, 16, iter_reg);
1976 iter_reg = qla24xx_read_window(reg, 0xFE30, 16, iter_reg);
1977 iter_reg = qla24xx_read_window(reg, 0xFE40, 16, iter_reg);
1978 iter_reg = qla24xx_read_window(reg, 0xFE50, 16, iter_reg);
1979 iter_reg = qla24xx_read_window(reg, 0xFE60, 16, iter_reg);
1980 iter_reg = qla24xx_read_window(reg, 0xFE70, 16, iter_reg);
1981 iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1982 iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1983 iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1984 iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1985 iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1986 iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1987 iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1988 qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
1989
1990 iter_reg = fw->rseq_0_reg;
1991 iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
1992 qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
1993
1994 qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1995 qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
1996 qla24xx_read_window(reg, 0xFEF0, 16, fw->rseq_3_reg);
1997
1998 /* Auxiliary sequence registers. */
1999 iter_reg = fw->aseq_gp_reg;
2000 iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
2001 iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
2002 iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
2003 iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
2004 iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
2005 iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
2006 iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
2007 iter_reg = qla24xx_read_window(reg, 0xB070, 16, iter_reg);
2008 iter_reg = qla24xx_read_window(reg, 0xB100, 16, iter_reg);
2009 iter_reg = qla24xx_read_window(reg, 0xB110, 16, iter_reg);
2010 iter_reg = qla24xx_read_window(reg, 0xB120, 16, iter_reg);
2011 iter_reg = qla24xx_read_window(reg, 0xB130, 16, iter_reg);
2012 iter_reg = qla24xx_read_window(reg, 0xB140, 16, iter_reg);
2013 iter_reg = qla24xx_read_window(reg, 0xB150, 16, iter_reg);
2014 iter_reg = qla24xx_read_window(reg, 0xB160, 16, iter_reg);
2015 qla24xx_read_window(reg, 0xB170, 16, iter_reg);
2016
2017 iter_reg = fw->aseq_0_reg;
2018 iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
2019 qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
2020
2021 qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
2022 qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
2023 qla24xx_read_window(reg, 0xB1F0, 16, fw->aseq_3_reg);
2024
2025 /* Command DMA registers. */
2026 iter_reg = fw->cmd_dma_reg;
2027 iter_reg = qla24xx_read_window(reg, 0x7100, 16, iter_reg);
2028 iter_reg = qla24xx_read_window(reg, 0x7120, 16, iter_reg);
2029 iter_reg = qla24xx_read_window(reg, 0x7130, 16, iter_reg);
2030 qla24xx_read_window(reg, 0x71F0, 16, iter_reg);
2031
2032 /* Queues. */
2033 iter_reg = fw->req0_dma_reg;
2034 iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
2035 dmp_reg = &reg->iobase_q;
2036 for (cnt = 0; cnt < 7; cnt++)
2037 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
2038
2039 iter_reg = fw->resp0_dma_reg;
2040 iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
2041 dmp_reg = &reg->iobase_q;
2042 for (cnt = 0; cnt < 7; cnt++)
2043 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
2044
2045 iter_reg = fw->req1_dma_reg;
2046 iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
2047 dmp_reg = &reg->iobase_q;
2048 for (cnt = 0; cnt < 7; cnt++)
2049 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
2050
2051 /* Transmit DMA registers. */
2052 iter_reg = fw->xmt0_dma_reg;
2053 iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
2054 qla24xx_read_window(reg, 0x7610, 16, iter_reg);
2055
2056 iter_reg = fw->xmt1_dma_reg;
2057 iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
2058 qla24xx_read_window(reg, 0x7630, 16, iter_reg);
2059
2060 iter_reg = fw->xmt2_dma_reg;
2061 iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
2062 qla24xx_read_window(reg, 0x7650, 16, iter_reg);
2063
2064 iter_reg = fw->xmt3_dma_reg;
2065 iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
2066 qla24xx_read_window(reg, 0x7670, 16, iter_reg);
2067
2068 iter_reg = fw->xmt4_dma_reg;
2069 iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
2070 qla24xx_read_window(reg, 0x7690, 16, iter_reg);
2071
2072 qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
2073
2074 /* Receive DMA registers. */
2075 iter_reg = fw->rcvt0_data_dma_reg;
2076 iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
2077 qla24xx_read_window(reg, 0x7710, 16, iter_reg);
2078
2079 iter_reg = fw->rcvt1_data_dma_reg;
2080 iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
2081 qla24xx_read_window(reg, 0x7730, 16, iter_reg);
2082
2083 /* RISC registers. */
2084 iter_reg = fw->risc_gp_reg;
2085 iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
2086 iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
2087 iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
2088 iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
2089 iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
2090 iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
2091 iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
2092 qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
2093
2094 /* Local memory controller registers. */
2095 iter_reg = fw->lmc_reg;
2096 iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
2097 iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
2098 iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
2099 iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
2100 iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
2101 iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
2102 iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
2103 qla24xx_read_window(reg, 0x3070, 16, iter_reg);
2104
2105 /* Fibre Protocol Module registers. */
2106 iter_reg = fw->fpm_hdw_reg;
2107 iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
2108 iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
2109 iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
2110 iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
2111 iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
2112 iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
2113 iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
2114 iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
2115 iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
2116 iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
2117 iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
2118 iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
2119 iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
2120 iter_reg = qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
2121 iter_reg = qla24xx_read_window(reg, 0x40E0, 16, iter_reg);
2122 qla24xx_read_window(reg, 0x40F0, 16, iter_reg);
2123
2124 /* RQ0 Array registers. */
2125 iter_reg = fw->rq0_array_reg;
2126 iter_reg = qla24xx_read_window(reg, 0x5C00, 16, iter_reg);
2127 iter_reg = qla24xx_read_window(reg, 0x5C10, 16, iter_reg);
2128 iter_reg = qla24xx_read_window(reg, 0x5C20, 16, iter_reg);
2129 iter_reg = qla24xx_read_window(reg, 0x5C30, 16, iter_reg);
2130 iter_reg = qla24xx_read_window(reg, 0x5C40, 16, iter_reg);
2131 iter_reg = qla24xx_read_window(reg, 0x5C50, 16, iter_reg);
2132 iter_reg = qla24xx_read_window(reg, 0x5C60, 16, iter_reg);
2133 iter_reg = qla24xx_read_window(reg, 0x5C70, 16, iter_reg);
2134 iter_reg = qla24xx_read_window(reg, 0x5C80, 16, iter_reg);
2135 iter_reg = qla24xx_read_window(reg, 0x5C90, 16, iter_reg);
2136 iter_reg = qla24xx_read_window(reg, 0x5CA0, 16, iter_reg);
2137 iter_reg = qla24xx_read_window(reg, 0x5CB0, 16, iter_reg);
2138 iter_reg = qla24xx_read_window(reg, 0x5CC0, 16, iter_reg);
2139 iter_reg = qla24xx_read_window(reg, 0x5CD0, 16, iter_reg);
2140 iter_reg = qla24xx_read_window(reg, 0x5CE0, 16, iter_reg);
2141 qla24xx_read_window(reg, 0x5CF0, 16, iter_reg);
2142
2143 /* RQ1 Array registers. */
2144 iter_reg = fw->rq1_array_reg;
2145 iter_reg = qla24xx_read_window(reg, 0x5D00, 16, iter_reg);
2146 iter_reg = qla24xx_read_window(reg, 0x5D10, 16, iter_reg);
2147 iter_reg = qla24xx_read_window(reg, 0x5D20, 16, iter_reg);
2148 iter_reg = qla24xx_read_window(reg, 0x5D30, 16, iter_reg);
2149 iter_reg = qla24xx_read_window(reg, 0x5D40, 16, iter_reg);
2150 iter_reg = qla24xx_read_window(reg, 0x5D50, 16, iter_reg);
2151 iter_reg = qla24xx_read_window(reg, 0x5D60, 16, iter_reg);
2152 iter_reg = qla24xx_read_window(reg, 0x5D70, 16, iter_reg);
2153 iter_reg = qla24xx_read_window(reg, 0x5D80, 16, iter_reg);
2154 iter_reg = qla24xx_read_window(reg, 0x5D90, 16, iter_reg);
2155 iter_reg = qla24xx_read_window(reg, 0x5DA0, 16, iter_reg);
2156 iter_reg = qla24xx_read_window(reg, 0x5DB0, 16, iter_reg);
2157 iter_reg = qla24xx_read_window(reg, 0x5DC0, 16, iter_reg);
2158 iter_reg = qla24xx_read_window(reg, 0x5DD0, 16, iter_reg);
2159 iter_reg = qla24xx_read_window(reg, 0x5DE0, 16, iter_reg);
2160 qla24xx_read_window(reg, 0x5DF0, 16, iter_reg);
2161
2162 /* RP0 Array registers. */
2163 iter_reg = fw->rp0_array_reg;
2164 iter_reg = qla24xx_read_window(reg, 0x5E00, 16, iter_reg);
2165 iter_reg = qla24xx_read_window(reg, 0x5E10, 16, iter_reg);
2166 iter_reg = qla24xx_read_window(reg, 0x5E20, 16, iter_reg);
2167 iter_reg = qla24xx_read_window(reg, 0x5E30, 16, iter_reg);
2168 iter_reg = qla24xx_read_window(reg, 0x5E40, 16, iter_reg);
2169 iter_reg = qla24xx_read_window(reg, 0x5E50, 16, iter_reg);
2170 iter_reg = qla24xx_read_window(reg, 0x5E60, 16, iter_reg);
2171 iter_reg = qla24xx_read_window(reg, 0x5E70, 16, iter_reg);
2172 iter_reg = qla24xx_read_window(reg, 0x5E80, 16, iter_reg);
2173 iter_reg = qla24xx_read_window(reg, 0x5E90, 16, iter_reg);
2174 iter_reg = qla24xx_read_window(reg, 0x5EA0, 16, iter_reg);
2175 iter_reg = qla24xx_read_window(reg, 0x5EB0, 16, iter_reg);
2176 iter_reg = qla24xx_read_window(reg, 0x5EC0, 16, iter_reg);
2177 iter_reg = qla24xx_read_window(reg, 0x5ED0, 16, iter_reg);
2178 iter_reg = qla24xx_read_window(reg, 0x5EE0, 16, iter_reg);
2179 qla24xx_read_window(reg, 0x5EF0, 16, iter_reg);
2180
2181 /* RP1 Array registers. */
2182 iter_reg = fw->rp1_array_reg;
2183 iter_reg = qla24xx_read_window(reg, 0x5F00, 16, iter_reg);
2184 iter_reg = qla24xx_read_window(reg, 0x5F10, 16, iter_reg);
2185 iter_reg = qla24xx_read_window(reg, 0x5F20, 16, iter_reg);
2186 iter_reg = qla24xx_read_window(reg, 0x5F30, 16, iter_reg);
2187 iter_reg = qla24xx_read_window(reg, 0x5F40, 16, iter_reg);
2188 iter_reg = qla24xx_read_window(reg, 0x5F50, 16, iter_reg);
2189 iter_reg = qla24xx_read_window(reg, 0x5F60, 16, iter_reg);
2190 iter_reg = qla24xx_read_window(reg, 0x5F70, 16, iter_reg);
2191 iter_reg = qla24xx_read_window(reg, 0x5F80, 16, iter_reg);
2192 iter_reg = qla24xx_read_window(reg, 0x5F90, 16, iter_reg);
2193 iter_reg = qla24xx_read_window(reg, 0x5FA0, 16, iter_reg);
2194 iter_reg = qla24xx_read_window(reg, 0x5FB0, 16, iter_reg);
2195 iter_reg = qla24xx_read_window(reg, 0x5FC0, 16, iter_reg);
2196 iter_reg = qla24xx_read_window(reg, 0x5FD0, 16, iter_reg);
2197 iter_reg = qla24xx_read_window(reg, 0x5FE0, 16, iter_reg);
2198 qla24xx_read_window(reg, 0x5FF0, 16, iter_reg);
2199
2200 iter_reg = fw->at0_array_reg;
2201 iter_reg = qla24xx_read_window(reg, 0x7080, 16, iter_reg);
2202 iter_reg = qla24xx_read_window(reg, 0x7090, 16, iter_reg);
2203 iter_reg = qla24xx_read_window(reg, 0x70A0, 16, iter_reg);
2204 iter_reg = qla24xx_read_window(reg, 0x70B0, 16, iter_reg);
2205 iter_reg = qla24xx_read_window(reg, 0x70C0, 16, iter_reg);
2206 iter_reg = qla24xx_read_window(reg, 0x70D0, 16, iter_reg);
2207 iter_reg = qla24xx_read_window(reg, 0x70E0, 16, iter_reg);
2208 qla24xx_read_window(reg, 0x70F0, 16, iter_reg);
2209
2210 /* I/O Queue Control registers. */
2211 qla24xx_read_window(reg, 0x7800, 16, fw->queue_control_reg);
2212
2213 /* Frame Buffer registers. */
2214 iter_reg = fw->fb_hdw_reg;
2215 iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
2216 iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
2217 iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
2218 iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
2219 iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
2220 iter_reg = qla24xx_read_window(reg, 0x6060, 16, iter_reg);
2221 iter_reg = qla24xx_read_window(reg, 0x6070, 16, iter_reg);
2222 iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
2223 iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
2224 iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
2225 iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
2226 iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
2227 iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
2228 iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
2229 iter_reg = qla24xx_read_window(reg, 0x6530, 16, iter_reg);
2230 iter_reg = qla24xx_read_window(reg, 0x6540, 16, iter_reg);
2231 iter_reg = qla24xx_read_window(reg, 0x6550, 16, iter_reg);
2232 iter_reg = qla24xx_read_window(reg, 0x6560, 16, iter_reg);
2233 iter_reg = qla24xx_read_window(reg, 0x6570, 16, iter_reg);
2234 iter_reg = qla24xx_read_window(reg, 0x6580, 16, iter_reg);
2235 iter_reg = qla24xx_read_window(reg, 0x6590, 16, iter_reg);
2236 iter_reg = qla24xx_read_window(reg, 0x65A0, 16, iter_reg);
2237 iter_reg = qla24xx_read_window(reg, 0x65B0, 16, iter_reg);
2238 iter_reg = qla24xx_read_window(reg, 0x65C0, 16, iter_reg);
2239 iter_reg = qla24xx_read_window(reg, 0x65D0, 16, iter_reg);
2240 iter_reg = qla24xx_read_window(reg, 0x65E0, 16, iter_reg);
2241 qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
2242
2243 /* Multi queue registers */
2244 nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
2245 &last_chain);
2246
2247 rval = qla24xx_soft_reset(ha);
2248 if (rval != QLA_SUCCESS) {
2249 ql_log(ql_log_warn, vha, 0xd00e,
2250 "SOFT RESET FAILED, forcing continuation of dump!!!\n");
2251 rval = QLA_SUCCESS;
2252
2253 ql_log(ql_log_warn, vha, 0xd00f, "try a bigger hammer!!!\n");
2254
2255 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
2256 RD_REG_DWORD(&reg->hccr);
2257
2258 WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
2259 RD_REG_DWORD(&reg->hccr);
2260
2261 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
2262 RD_REG_DWORD(&reg->hccr);
2263
2264 for (cnt = 30000; cnt && (RD_REG_WORD(&reg->mailbox0)); cnt--)
2265 udelay(5);
2266
2267 if (!cnt) {
2268 nxt = fw->code_ram;
2269 nxt += sizeof(fw->code_ram),
2270 nxt += (ha->fw_memory_size - 0x100000 + 1);
2271 goto copy_queue;
2272 } else
2273 ql_log(ql_log_warn, vha, 0xd010,
2274 "bigger hammer success?\n");
2275 }
2276
2277 rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
2278 &nxt);
2279 if (rval != QLA_SUCCESS)
2280 goto qla83xx_fw_dump_failed_0;
2281
2282copy_queue:
2283 nxt = qla2xxx_copy_queues(ha, nxt);
2284
2285 nxt = qla24xx_copy_eft(ha, nxt);
2286
2287 /* Chain entries -- started with MQ. */
2288 nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
2289 nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04002290 nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002291 if (last_chain) {
2292 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
2293 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
2294 }
2295
2296 /* Adjust valid length. */
2297 ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
2298
2299qla83xx_fw_dump_failed_0:
2300 qla2xxx_dump_post_process(base_vha, rval);
2301
2302qla83xx_fw_dump_failed:
2303 if (!hardware_locked)
2304 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2305}
2306
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307/****************************************************************************/
2308/* Driver Debug Functions. */
2309/****************************************************************************/
Chad Dupuiscfb09192011-11-18 09:03:07 -08002310
2311static inline int
2312ql_mask_match(uint32_t level)
2313{
2314 if (ql2xextended_error_logging == 1)
2315 ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK;
2316 return (level & ql2xextended_error_logging) == level;
2317}
2318
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002319/*
2320 * This function is for formatting and logging debug information.
2321 * It is to be used when vha is available. It formats the message
2322 * and logs it to the messages file.
2323 * parameters:
2324 * level: The level of the debug messages to be printed.
2325 * If ql2xextended_error_logging value is correctly set,
2326 * this message will appear in the messages file.
2327 * vha: Pointer to the scsi_qla_host_t.
2328 * id: This is a unique identifier for the level. It identifies the
2329 * part of the code from where the message originated.
2330 * msg: The message to be displayed.
2331 */
2332void
Joe Perches086b3e82011-11-18 09:03:05 -08002333ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...)
2334{
2335 va_list va;
2336 struct va_format vaf;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002337
Chad Dupuiscfb09192011-11-18 09:03:07 -08002338 if (!ql_mask_match(level))
Joe Perches086b3e82011-11-18 09:03:05 -08002339 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002340
Joe Perches086b3e82011-11-18 09:03:05 -08002341 va_start(va, fmt);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002342
Joe Perches086b3e82011-11-18 09:03:05 -08002343 vaf.fmt = fmt;
2344 vaf.va = &va;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002345
Joe Perches086b3e82011-11-18 09:03:05 -08002346 if (vha != NULL) {
2347 const struct pci_dev *pdev = vha->hw->pdev;
2348 /* <module-name> <pci-name> <msg-id>:<host> Message */
2349 pr_warn("%s [%s]-%04x:%ld: %pV",
2350 QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset,
2351 vha->host_no, &vaf);
2352 } else {
2353 pr_warn("%s [%s]-%04x: : %pV",
2354 QL_MSGHDR, "0000:00:00.0", id + ql_dbg_offset, &vaf);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002355 }
2356
Joe Perches086b3e82011-11-18 09:03:05 -08002357 va_end(va);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002358
2359}
2360
2361/*
2362 * This function is for formatting and logging debug information.
Masanari Iidad6a03582012-08-22 14:20:58 -04002363 * It is to be used when vha is not available and pci is available,
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002364 * i.e., before host allocation. It formats the message and logs it
2365 * to the messages file.
2366 * parameters:
2367 * level: The level of the debug messages to be printed.
2368 * If ql2xextended_error_logging value is correctly set,
2369 * this message will appear in the messages file.
2370 * pdev: Pointer to the struct pci_dev.
2371 * id: This is a unique id for the level. It identifies the part
2372 * of the code from where the message originated.
2373 * msg: The message to be displayed.
2374 */
2375void
Joe Perches086b3e82011-11-18 09:03:05 -08002376ql_dbg_pci(uint32_t level, struct pci_dev *pdev, int32_t id,
2377 const char *fmt, ...)
2378{
2379 va_list va;
2380 struct va_format vaf;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002381
2382 if (pdev == NULL)
2383 return;
Chad Dupuiscfb09192011-11-18 09:03:07 -08002384 if (!ql_mask_match(level))
Joe Perches086b3e82011-11-18 09:03:05 -08002385 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002386
Joe Perches086b3e82011-11-18 09:03:05 -08002387 va_start(va, fmt);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002388
Joe Perches086b3e82011-11-18 09:03:05 -08002389 vaf.fmt = fmt;
2390 vaf.va = &va;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002391
Joe Perches086b3e82011-11-18 09:03:05 -08002392 /* <module-name> <dev-name>:<msg-id> Message */
2393 pr_warn("%s [%s]-%04x: : %pV",
2394 QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset, &vaf);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002395
Joe Perches086b3e82011-11-18 09:03:05 -08002396 va_end(va);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002397}
2398
2399/*
2400 * This function is for formatting and logging log messages.
2401 * It is to be used when vha is available. It formats the message
2402 * and logs it to the messages file. All the messages will be logged
2403 * irrespective of value of ql2xextended_error_logging.
2404 * parameters:
2405 * level: The level of the log messages to be printed in the
2406 * messages file.
2407 * vha: Pointer to the scsi_qla_host_t
2408 * id: This is a unique id for the level. It identifies the
2409 * part of the code from where the message originated.
2410 * msg: The message to be displayed.
2411 */
2412void
Joe Perches086b3e82011-11-18 09:03:05 -08002413ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...)
2414{
2415 va_list va;
2416 struct va_format vaf;
2417 char pbuf[128];
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002418
Joe Perches086b3e82011-11-18 09:03:05 -08002419 if (level > ql_errlev)
2420 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002421
Joe Perches086b3e82011-11-18 09:03:05 -08002422 if (vha != NULL) {
2423 const struct pci_dev *pdev = vha->hw->pdev;
2424 /* <module-name> <msg-id>:<host> Message */
2425 snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x:%ld: ",
2426 QL_MSGHDR, dev_name(&(pdev->dev)), id, vha->host_no);
2427 } else {
2428 snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
2429 QL_MSGHDR, "0000:00:00.0", id);
2430 }
2431 pbuf[sizeof(pbuf) - 1] = 0;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002432
Joe Perches086b3e82011-11-18 09:03:05 -08002433 va_start(va, fmt);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002434
Joe Perches086b3e82011-11-18 09:03:05 -08002435 vaf.fmt = fmt;
2436 vaf.va = &va;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002437
Joe Perches086b3e82011-11-18 09:03:05 -08002438 switch (level) {
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002439 case ql_log_fatal: /* FATAL LOG */
Joe Perches086b3e82011-11-18 09:03:05 -08002440 pr_crit("%s%pV", pbuf, &vaf);
2441 break;
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002442 case ql_log_warn:
Joe Perches086b3e82011-11-18 09:03:05 -08002443 pr_err("%s%pV", pbuf, &vaf);
2444 break;
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002445 case ql_log_info:
Joe Perches086b3e82011-11-18 09:03:05 -08002446 pr_warn("%s%pV", pbuf, &vaf);
2447 break;
2448 default:
2449 pr_info("%s%pV", pbuf, &vaf);
2450 break;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002451 }
2452
Joe Perches086b3e82011-11-18 09:03:05 -08002453 va_end(va);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002454}
2455
2456/*
2457 * This function is for formatting and logging log messages.
Masanari Iidad6a03582012-08-22 14:20:58 -04002458 * It is to be used when vha is not available and pci is available,
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002459 * i.e., before host allocation. It formats the message and logs
2460 * it to the messages file. All the messages are logged irrespective
2461 * of the value of ql2xextended_error_logging.
2462 * parameters:
2463 * level: The level of the log messages to be printed in the
2464 * messages file.
2465 * pdev: Pointer to the struct pci_dev.
2466 * id: This is a unique id for the level. It identifies the
2467 * part of the code from where the message originated.
2468 * msg: The message to be displayed.
2469 */
2470void
Joe Perches086b3e82011-11-18 09:03:05 -08002471ql_log_pci(uint32_t level, struct pci_dev *pdev, int32_t id,
2472 const char *fmt, ...)
2473{
2474 va_list va;
2475 struct va_format vaf;
2476 char pbuf[128];
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002477
2478 if (pdev == NULL)
2479 return;
Joe Perches086b3e82011-11-18 09:03:05 -08002480 if (level > ql_errlev)
2481 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002482
Joe Perches086b3e82011-11-18 09:03:05 -08002483 /* <module-name> <dev-name>:<msg-id> Message */
2484 snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
2485 QL_MSGHDR, dev_name(&(pdev->dev)), id);
2486 pbuf[sizeof(pbuf) - 1] = 0;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002487
Joe Perches086b3e82011-11-18 09:03:05 -08002488 va_start(va, fmt);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002489
Joe Perches086b3e82011-11-18 09:03:05 -08002490 vaf.fmt = fmt;
2491 vaf.va = &va;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002492
Joe Perches086b3e82011-11-18 09:03:05 -08002493 switch (level) {
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002494 case ql_log_fatal: /* FATAL LOG */
Joe Perches086b3e82011-11-18 09:03:05 -08002495 pr_crit("%s%pV", pbuf, &vaf);
2496 break;
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002497 case ql_log_warn:
Joe Perches086b3e82011-11-18 09:03:05 -08002498 pr_err("%s%pV", pbuf, &vaf);
2499 break;
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002500 case ql_log_info:
Joe Perches086b3e82011-11-18 09:03:05 -08002501 pr_warn("%s%pV", pbuf, &vaf);
2502 break;
2503 default:
2504 pr_info("%s%pV", pbuf, &vaf);
2505 break;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002506 }
2507
Joe Perches086b3e82011-11-18 09:03:05 -08002508 va_end(va);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002509}
2510
2511void
2512ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id)
2513{
2514 int i;
2515 struct qla_hw_data *ha = vha->hw;
2516 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
2517 struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
2518 struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
2519 uint16_t __iomem *mbx_reg;
2520
Chad Dupuiscfb09192011-11-18 09:03:07 -08002521 if (!ql_mask_match(level))
2522 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002523
Chad Dupuiscfb09192011-11-18 09:03:07 -08002524 if (IS_QLA82XX(ha))
2525 mbx_reg = &reg82->mailbox_in[0];
2526 else if (IS_FWI2_CAPABLE(ha))
2527 mbx_reg = &reg24->mailbox0;
2528 else
2529 mbx_reg = MAILBOX_REG(ha, reg, 0);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002530
Chad Dupuiscfb09192011-11-18 09:03:07 -08002531 ql_dbg(level, vha, id, "Mailbox registers:\n");
2532 for (i = 0; i < 6; i++)
2533 ql_dbg(level, vha, id,
2534 "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg++));
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002535}
2536
2537
2538void
2539ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, int32_t id,
2540 uint8_t *b, uint32_t size)
2541{
2542 uint32_t cnt;
2543 uint8_t c;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002544
Chad Dupuiscfb09192011-11-18 09:03:07 -08002545 if (!ql_mask_match(level))
2546 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002547
Chad Dupuiscfb09192011-11-18 09:03:07 -08002548 ql_dbg(level, vha, id, " 0 1 2 3 4 5 6 7 8 "
2549 "9 Ah Bh Ch Dh Eh Fh\n");
2550 ql_dbg(level, vha, id, "----------------------------------"
2551 "----------------------------\n");
2552
2553 ql_dbg(level, vha, id, " ");
2554 for (cnt = 0; cnt < size;) {
2555 c = *b++;
2556 printk("%02x", (uint32_t) c);
2557 cnt++;
2558 if (!(cnt % 16))
2559 printk("\n");
2560 else
2561 printk(" ");
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002562 }
Chad Dupuiscfb09192011-11-18 09:03:07 -08002563 if (cnt % 16)
2564 ql_dbg(level, vha, id, "\n");
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002565}