blob: 2d9b12ffe09c3b9f85ecdd2d2f03d19dc91aa2d7 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2005 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 */
7#include "qla_def.h"
8
9#include <linux/delay.h>
10
11static int qla_uprintf(char **, char *, ...);
12
13/**
14 * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
15 * @ha: HA context
16 * @hardware_locked: Called with the hardware_lock
17 */
18void
19qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
20{
21 int rval;
22 uint32_t cnt, timer;
23 uint32_t risc_address;
24 uint16_t mb0, mb2;
25
26 uint32_t stat;
Andrew Vasquez3d716442005-07-06 10:30:26 -070027 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
Linus Torvalds1da177e2005-04-16 15:20:36 -070028 uint16_t __iomem *dmp_reg;
29 unsigned long flags;
30 struct qla2300_fw_dump *fw;
31 uint32_t dump_size, data_ram_cnt;
32
33 risc_address = data_ram_cnt = 0;
34 mb0 = mb2 = 0;
35 flags = 0;
36
37 if (!hardware_locked)
38 spin_lock_irqsave(&ha->hardware_lock, flags);
39
40 if (ha->fw_dump != NULL) {
41 qla_printk(KERN_WARNING, ha,
42 "Firmware has been previously dumped (%p) -- ignoring "
43 "request...\n", ha->fw_dump);
44 goto qla2300_fw_dump_failed;
45 }
46
47 /* Allocate (large) dump buffer. */
48 dump_size = sizeof(struct qla2300_fw_dump);
49 dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t);
50 ha->fw_dump_order = get_order(dump_size);
51 ha->fw_dump = (struct qla2300_fw_dump *) __get_free_pages(GFP_ATOMIC,
52 ha->fw_dump_order);
53 if (ha->fw_dump == NULL) {
54 qla_printk(KERN_WARNING, ha,
55 "Unable to allocated memory for firmware dump (%d/%d).\n",
56 ha->fw_dump_order, dump_size);
57 goto qla2300_fw_dump_failed;
58 }
59 fw = ha->fw_dump;
60
61 rval = QLA_SUCCESS;
62 fw->hccr = RD_REG_WORD(&reg->hccr);
63
64 /* Pause RISC. */
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -070065 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 if (IS_QLA2300(ha)) {
67 for (cnt = 30000;
68 (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
69 rval == QLA_SUCCESS; cnt--) {
70 if (cnt)
71 udelay(100);
72 else
73 rval = QLA_FUNCTION_TIMEOUT;
74 }
75 } else {
76 RD_REG_WORD(&reg->hccr); /* PCI Posting. */
77 udelay(10);
78 }
79
80 if (rval == QLA_SUCCESS) {
81 dmp_reg = (uint16_t __iomem *)(reg + 0);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -070082 for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++);
84
85 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -070086 for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 fw->risc_host_reg[cnt] = RD_REG_WORD(dmp_reg++);
88
89 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -070090 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++);
92
93 WRT_REG_WORD(&reg->ctrl_status, 0x40);
94 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -070095 for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 fw->resp_dma_reg[cnt] = RD_REG_WORD(dmp_reg++);
97
98 WRT_REG_WORD(&reg->ctrl_status, 0x50);
99 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700100 for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++);
102
103 WRT_REG_WORD(&reg->ctrl_status, 0x00);
104 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700105 for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++);
107
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700108 WRT_REG_WORD(&reg->pcr, 0x2000);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700110 for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++);
112
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700113 WRT_REG_WORD(&reg->pcr, 0x2200);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700115 for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++);
117
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700118 WRT_REG_WORD(&reg->pcr, 0x2400);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700120 for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++);
122
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700123 WRT_REG_WORD(&reg->pcr, 0x2600);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700125 for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++);
127
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700128 WRT_REG_WORD(&reg->pcr, 0x2800);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700130 for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131 fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++);
132
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700133 WRT_REG_WORD(&reg->pcr, 0x2A00);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700135 for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++);
137
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700138 WRT_REG_WORD(&reg->pcr, 0x2C00);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700140 for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141 fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++);
142
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700143 WRT_REG_WORD(&reg->pcr, 0x2E00);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700145 for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++);
147
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700148 WRT_REG_WORD(&reg->ctrl_status, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700150 for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++);
152
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700153 WRT_REG_WORD(&reg->ctrl_status, 0x20);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700155 for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++);
157
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700158 WRT_REG_WORD(&reg->ctrl_status, 0x30);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700160 for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++);
162
163 /* Reset RISC. */
164 WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
165 for (cnt = 0; cnt < 30000; cnt++) {
166 if ((RD_REG_WORD(&reg->ctrl_status) &
167 CSR_ISP_SOFT_RESET) == 0)
168 break;
169
170 udelay(10);
171 }
172 }
173
174 if (!IS_QLA2300(ha)) {
175 for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
176 rval == QLA_SUCCESS; cnt--) {
177 if (cnt)
178 udelay(100);
179 else
180 rval = QLA_FUNCTION_TIMEOUT;
181 }
182 }
183
184 if (rval == QLA_SUCCESS) {
185 /* Get RISC SRAM. */
186 risc_address = 0x800;
187 WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
188 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
189 }
190 for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;
191 cnt++, risc_address++) {
192 WRT_MAILBOX_REG(ha, reg, 1, (uint16_t)risc_address);
193 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
194
195 for (timer = 6000000; timer; timer--) {
196 /* Check for pending interrupts. */
197 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
198 if (stat & HSR_RISC_INT) {
199 stat &= 0xff;
200
201 if (stat == 0x1 || stat == 0x2) {
202 set_bit(MBX_INTERRUPT,
203 &ha->mbx_cmd_flags);
204
205 mb0 = RD_MAILBOX_REG(ha, reg, 0);
206 mb2 = RD_MAILBOX_REG(ha, reg, 2);
207
208 /* Release mailbox registers. */
209 WRT_REG_WORD(&reg->semaphore, 0);
210 WRT_REG_WORD(&reg->hccr,
211 HCCR_CLR_RISC_INT);
212 RD_REG_WORD(&reg->hccr);
213 break;
214 } else if (stat == 0x10 || stat == 0x11) {
215 set_bit(MBX_INTERRUPT,
216 &ha->mbx_cmd_flags);
217
218 mb0 = RD_MAILBOX_REG(ha, reg, 0);
219 mb2 = RD_MAILBOX_REG(ha, reg, 2);
220
221 WRT_REG_WORD(&reg->hccr,
222 HCCR_CLR_RISC_INT);
223 RD_REG_WORD(&reg->hccr);
224 break;
225 }
226
227 /* clear this intr; it wasn't a mailbox intr */
228 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
229 RD_REG_WORD(&reg->hccr);
230 }
231 udelay(5);
232 }
233
234 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
235 rval = mb0 & MBS_MASK;
236 fw->risc_ram[cnt] = mb2;
237 } else {
238 rval = QLA_FUNCTION_FAILED;
239 }
240 }
241
242 if (rval == QLA_SUCCESS) {
243 /* Get stack SRAM. */
244 risc_address = 0x10000;
245 WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED);
246 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
247 }
248 for (cnt = 0; cnt < sizeof(fw->stack_ram) / 2 && rval == QLA_SUCCESS;
249 cnt++, risc_address++) {
250 WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address));
251 WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address));
252 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
253
254 for (timer = 6000000; timer; timer--) {
255 /* Check for pending interrupts. */
256 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
257 if (stat & HSR_RISC_INT) {
258 stat &= 0xff;
259
260 if (stat == 0x1 || stat == 0x2) {
261 set_bit(MBX_INTERRUPT,
262 &ha->mbx_cmd_flags);
263
264 mb0 = RD_MAILBOX_REG(ha, reg, 0);
265 mb2 = RD_MAILBOX_REG(ha, reg, 2);
266
267 /* Release mailbox registers. */
268 WRT_REG_WORD(&reg->semaphore, 0);
269 WRT_REG_WORD(&reg->hccr,
270 HCCR_CLR_RISC_INT);
271 RD_REG_WORD(&reg->hccr);
272 break;
273 } else if (stat == 0x10 || stat == 0x11) {
274 set_bit(MBX_INTERRUPT,
275 &ha->mbx_cmd_flags);
276
277 mb0 = RD_MAILBOX_REG(ha, reg, 0);
278 mb2 = RD_MAILBOX_REG(ha, reg, 2);
279
280 WRT_REG_WORD(&reg->hccr,
281 HCCR_CLR_RISC_INT);
282 RD_REG_WORD(&reg->hccr);
283 break;
284 }
285
286 /* clear this intr; it wasn't a mailbox intr */
287 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
288 RD_REG_WORD(&reg->hccr);
289 }
290 udelay(5);
291 }
292
293 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
294 rval = mb0 & MBS_MASK;
295 fw->stack_ram[cnt] = mb2;
296 } else {
297 rval = QLA_FUNCTION_FAILED;
298 }
299 }
300
301 if (rval == QLA_SUCCESS) {
302 /* Get data SRAM. */
303 risc_address = 0x11000;
304 data_ram_cnt = ha->fw_memory_size - risc_address + 1;
305 WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED);
306 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
307 }
308 for (cnt = 0; cnt < data_ram_cnt && rval == QLA_SUCCESS;
309 cnt++, risc_address++) {
310 WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address));
311 WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address));
312 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
313
314 for (timer = 6000000; timer; timer--) {
315 /* Check for pending interrupts. */
316 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
317 if (stat & HSR_RISC_INT) {
318 stat &= 0xff;
319
320 if (stat == 0x1 || stat == 0x2) {
321 set_bit(MBX_INTERRUPT,
322 &ha->mbx_cmd_flags);
323
324 mb0 = RD_MAILBOX_REG(ha, reg, 0);
325 mb2 = RD_MAILBOX_REG(ha, reg, 2);
326
327 /* Release mailbox registers. */
328 WRT_REG_WORD(&reg->semaphore, 0);
329 WRT_REG_WORD(&reg->hccr,
330 HCCR_CLR_RISC_INT);
331 RD_REG_WORD(&reg->hccr);
332 break;
333 } else if (stat == 0x10 || stat == 0x11) {
334 set_bit(MBX_INTERRUPT,
335 &ha->mbx_cmd_flags);
336
337 mb0 = RD_MAILBOX_REG(ha, reg, 0);
338 mb2 = RD_MAILBOX_REG(ha, reg, 2);
339
340 WRT_REG_WORD(&reg->hccr,
341 HCCR_CLR_RISC_INT);
342 RD_REG_WORD(&reg->hccr);
343 break;
344 }
345
346 /* clear this intr; it wasn't a mailbox intr */
347 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
348 RD_REG_WORD(&reg->hccr);
349 }
350 udelay(5);
351 }
352
353 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
354 rval = mb0 & MBS_MASK;
355 fw->data_ram[cnt] = mb2;
356 } else {
357 rval = QLA_FUNCTION_FAILED;
358 }
359 }
360
361
362 if (rval != QLA_SUCCESS) {
363 qla_printk(KERN_WARNING, ha,
364 "Failed to dump firmware (%x)!!!\n", rval);
365
366 free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order);
367 ha->fw_dump = NULL;
368 } else {
369 qla_printk(KERN_INFO, ha,
370 "Firmware dump saved to temp buffer (%ld/%p).\n",
371 ha->host_no, ha->fw_dump);
372 }
373
374qla2300_fw_dump_failed:
375 if (!hardware_locked)
376 spin_unlock_irqrestore(&ha->hardware_lock, flags);
377}
378
379/**
380 * qla2300_ascii_fw_dump() - Converts a binary firmware dump to ASCII.
381 * @ha: HA context
382 */
383void
384qla2300_ascii_fw_dump(scsi_qla_host_t *ha)
385{
386 uint32_t cnt;
387 char *uiter;
388 char fw_info[30];
389 struct qla2300_fw_dump *fw;
390 uint32_t data_ram_cnt;
391
392 uiter = ha->fw_dump_buffer;
393 fw = ha->fw_dump;
394
395 qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number,
Andrew Vasquezabbd8872005-07-06 10:30:05 -0700396 ha->isp_ops.fw_version_str(ha, fw_info));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
398 qla_uprintf(&uiter, "\n[==>BEG]\n");
399
400 qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr);
401
402 qla_uprintf(&uiter, "PBIU Registers:");
403 for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) {
404 if (cnt % 8 == 0) {
405 qla_uprintf(&uiter, "\n");
406 }
407 qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]);
408 }
409
410 qla_uprintf(&uiter, "\n\nReqQ-RspQ-Risc2Host Status registers:");
411 for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) {
412 if (cnt % 8 == 0) {
413 qla_uprintf(&uiter, "\n");
414 }
415 qla_uprintf(&uiter, "%04x ", fw->risc_host_reg[cnt]);
416 }
417
418 qla_uprintf(&uiter, "\n\nMailbox Registers:");
419 for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
420 if (cnt % 8 == 0) {
421 qla_uprintf(&uiter, "\n");
422 }
423 qla_uprintf(&uiter, "%04x ", fw->mailbox_reg[cnt]);
424 }
425
426 qla_uprintf(&uiter, "\n\nAuto Request Response DMA Registers:");
427 for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) {
428 if (cnt % 8 == 0) {
429 qla_uprintf(&uiter, "\n");
430 }
431 qla_uprintf(&uiter, "%04x ", fw->resp_dma_reg[cnt]);
432 }
433
434 qla_uprintf(&uiter, "\n\nDMA Registers:");
435 for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) {
436 if (cnt % 8 == 0) {
437 qla_uprintf(&uiter, "\n");
438 }
439 qla_uprintf(&uiter, "%04x ", fw->dma_reg[cnt]);
440 }
441
442 qla_uprintf(&uiter, "\n\nRISC Hardware Registers:");
443 for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) {
444 if (cnt % 8 == 0) {
445 qla_uprintf(&uiter, "\n");
446 }
447 qla_uprintf(&uiter, "%04x ", fw->risc_hdw_reg[cnt]);
448 }
449
450 qla_uprintf(&uiter, "\n\nRISC GP0 Registers:");
451 for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) {
452 if (cnt % 8 == 0) {
453 qla_uprintf(&uiter, "\n");
454 }
455 qla_uprintf(&uiter, "%04x ", fw->risc_gp0_reg[cnt]);
456 }
457
458 qla_uprintf(&uiter, "\n\nRISC GP1 Registers:");
459 for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) {
460 if (cnt % 8 == 0) {
461 qla_uprintf(&uiter, "\n");
462 }
463 qla_uprintf(&uiter, "%04x ", fw->risc_gp1_reg[cnt]);
464 }
465
466 qla_uprintf(&uiter, "\n\nRISC GP2 Registers:");
467 for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) {
468 if (cnt % 8 == 0) {
469 qla_uprintf(&uiter, "\n");
470 }
471 qla_uprintf(&uiter, "%04x ", fw->risc_gp2_reg[cnt]);
472 }
473
474 qla_uprintf(&uiter, "\n\nRISC GP3 Registers:");
475 for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) {
476 if (cnt % 8 == 0) {
477 qla_uprintf(&uiter, "\n");
478 }
479 qla_uprintf(&uiter, "%04x ", fw->risc_gp3_reg[cnt]);
480 }
481
482 qla_uprintf(&uiter, "\n\nRISC GP4 Registers:");
483 for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) {
484 if (cnt % 8 == 0) {
485 qla_uprintf(&uiter, "\n");
486 }
487 qla_uprintf(&uiter, "%04x ", fw->risc_gp4_reg[cnt]);
488 }
489
490 qla_uprintf(&uiter, "\n\nRISC GP5 Registers:");
491 for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) {
492 if (cnt % 8 == 0) {
493 qla_uprintf(&uiter, "\n");
494 }
495 qla_uprintf(&uiter, "%04x ", fw->risc_gp5_reg[cnt]);
496 }
497
498 qla_uprintf(&uiter, "\n\nRISC GP6 Registers:");
499 for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) {
500 if (cnt % 8 == 0) {
501 qla_uprintf(&uiter, "\n");
502 }
503 qla_uprintf(&uiter, "%04x ", fw->risc_gp6_reg[cnt]);
504 }
505
506 qla_uprintf(&uiter, "\n\nRISC GP7 Registers:");
507 for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) {
508 if (cnt % 8 == 0) {
509 qla_uprintf(&uiter, "\n");
510 }
511 qla_uprintf(&uiter, "%04x ", fw->risc_gp7_reg[cnt]);
512 }
513
514 qla_uprintf(&uiter, "\n\nFrame Buffer Hardware Registers:");
515 for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) {
516 if (cnt % 8 == 0) {
517 qla_uprintf(&uiter, "\n");
518 }
519 qla_uprintf(&uiter, "%04x ", fw->frame_buf_hdw_reg[cnt]);
520 }
521
522 qla_uprintf(&uiter, "\n\nFPM B0 Registers:");
523 for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) {
524 if (cnt % 8 == 0) {
525 qla_uprintf(&uiter, "\n");
526 }
527 qla_uprintf(&uiter, "%04x ", fw->fpm_b0_reg[cnt]);
528 }
529
530 qla_uprintf(&uiter, "\n\nFPM B1 Registers:");
531 for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) {
532 if (cnt % 8 == 0) {
533 qla_uprintf(&uiter, "\n");
534 }
535 qla_uprintf(&uiter, "%04x ", fw->fpm_b1_reg[cnt]);
536 }
537
538 qla_uprintf(&uiter, "\n\nCode RAM Dump:");
539 for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) {
540 if (cnt % 8 == 0) {
541 qla_uprintf(&uiter, "\n%04x: ", cnt + 0x0800);
542 }
543 qla_uprintf(&uiter, "%04x ", fw->risc_ram[cnt]);
544 }
545
546 qla_uprintf(&uiter, "\n\nStack RAM Dump:");
547 for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) {
548 if (cnt % 8 == 0) {
549 qla_uprintf(&uiter, "\n%05x: ", cnt + 0x10000);
550 }
551 qla_uprintf(&uiter, "%04x ", fw->stack_ram[cnt]);
552 }
553
554 qla_uprintf(&uiter, "\n\nData RAM Dump:");
555 data_ram_cnt = ha->fw_memory_size - 0x11000 + 1;
556 for (cnt = 0; cnt < data_ram_cnt; cnt++) {
557 if (cnt % 8 == 0) {
558 qla_uprintf(&uiter, "\n%05x: ", cnt + 0x11000);
559 }
560 qla_uprintf(&uiter, "%04x ", fw->data_ram[cnt]);
561 }
562
563 qla_uprintf(&uiter, "\n\n[<==END] ISP Debug Dump.");
564}
565
566/**
567 * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware.
568 * @ha: HA context
569 * @hardware_locked: Called with the hardware_lock
570 */
571void
572qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
573{
574 int rval;
575 uint32_t cnt, timer;
576 uint16_t risc_address;
577 uint16_t mb0, mb2;
Andrew Vasquez3d716442005-07-06 10:30:26 -0700578 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 uint16_t __iomem *dmp_reg;
580 unsigned long flags;
581 struct qla2100_fw_dump *fw;
582
583 risc_address = 0;
584 mb0 = mb2 = 0;
585 flags = 0;
586
587 if (!hardware_locked)
588 spin_lock_irqsave(&ha->hardware_lock, flags);
589
590 if (ha->fw_dump != NULL) {
591 qla_printk(KERN_WARNING, ha,
592 "Firmware has been previously dumped (%p) -- ignoring "
593 "request...\n", ha->fw_dump);
594 goto qla2100_fw_dump_failed;
595 }
596
597 /* Allocate (large) dump buffer. */
598 ha->fw_dump_order = get_order(sizeof(struct qla2100_fw_dump));
599 ha->fw_dump = (struct qla2100_fw_dump *) __get_free_pages(GFP_ATOMIC,
600 ha->fw_dump_order);
601 if (ha->fw_dump == NULL) {
602 qla_printk(KERN_WARNING, ha,
603 "Unable to allocated memory for firmware dump (%d/%Zd).\n",
604 ha->fw_dump_order, sizeof(struct qla2100_fw_dump));
605 goto qla2100_fw_dump_failed;
606 }
607 fw = ha->fw_dump;
608
609 rval = QLA_SUCCESS;
610 fw->hccr = RD_REG_WORD(&reg->hccr);
611
612 /* Pause RISC. */
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700613 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 for (cnt = 30000; (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
615 rval == QLA_SUCCESS; cnt--) {
616 if (cnt)
617 udelay(100);
618 else
619 rval = QLA_FUNCTION_TIMEOUT;
620 }
621 if (rval == QLA_SUCCESS) {
622 dmp_reg = (uint16_t __iomem *)(reg + 0);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700623 for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++);
625
626 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10);
627 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
628 if (cnt == 8) {
629 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xe0);
630 }
631 fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++);
632 }
633
634 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700635 for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++);
637
638 WRT_REG_WORD(&reg->ctrl_status, 0x00);
639 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700640 for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++);
642
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700643 WRT_REG_WORD(&reg->pcr, 0x2000);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700645 for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++);
647
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700648 WRT_REG_WORD(&reg->pcr, 0x2100);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700650 for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++);
652
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700653 WRT_REG_WORD(&reg->pcr, 0x2200);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700655 for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++);
657
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700658 WRT_REG_WORD(&reg->pcr, 0x2300);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700660 for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++);
662
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700663 WRT_REG_WORD(&reg->pcr, 0x2400);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700665 for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++);
667
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700668 WRT_REG_WORD(&reg->pcr, 0x2500);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700670 for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++);
672
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700673 WRT_REG_WORD(&reg->pcr, 0x2600);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700675 for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++);
677
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700678 WRT_REG_WORD(&reg->pcr, 0x2700);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700680 for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++);
682
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700683 WRT_REG_WORD(&reg->ctrl_status, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700685 for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++);
687
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700688 WRT_REG_WORD(&reg->ctrl_status, 0x20);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700690 for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++);
692
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700693 WRT_REG_WORD(&reg->ctrl_status, 0x30);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700695 for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++);
697
698 /* Reset the ISP. */
699 WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
700 }
701
702 for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
703 rval == QLA_SUCCESS; cnt--) {
704 if (cnt)
705 udelay(100);
706 else
707 rval = QLA_FUNCTION_TIMEOUT;
708 }
709
710 /* Pause RISC. */
711 if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) &&
712 (RD_REG_WORD(&reg->mctr) & (BIT_1 | BIT_0)) != 0))) {
713
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700714 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 for (cnt = 30000;
716 (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
717 rval == QLA_SUCCESS; cnt--) {
718 if (cnt)
719 udelay(100);
720 else
721 rval = QLA_FUNCTION_TIMEOUT;
722 }
723 if (rval == QLA_SUCCESS) {
724 /* Set memory configuration and timing. */
725 if (IS_QLA2100(ha))
726 WRT_REG_WORD(&reg->mctr, 0xf1);
727 else
728 WRT_REG_WORD(&reg->mctr, 0xf2);
729 RD_REG_WORD(&reg->mctr); /* PCI Posting. */
730
731 /* Release RISC. */
732 WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
733 }
734 }
735
736 if (rval == QLA_SUCCESS) {
737 /* Get RISC SRAM. */
738 risc_address = 0x1000;
739 WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
740 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
741 }
742 for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;
743 cnt++, risc_address++) {
744 WRT_MAILBOX_REG(ha, reg, 1, risc_address);
745 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
746
747 for (timer = 6000000; timer != 0; timer--) {
748 /* Check for pending interrupts. */
749 if (RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) {
750 if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
751 set_bit(MBX_INTERRUPT,
752 &ha->mbx_cmd_flags);
753
754 mb0 = RD_MAILBOX_REG(ha, reg, 0);
755 mb2 = RD_MAILBOX_REG(ha, reg, 2);
756
757 WRT_REG_WORD(&reg->semaphore, 0);
758 WRT_REG_WORD(&reg->hccr,
759 HCCR_CLR_RISC_INT);
760 RD_REG_WORD(&reg->hccr);
761 break;
762 }
763 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
764 RD_REG_WORD(&reg->hccr);
765 }
766 udelay(5);
767 }
768
769 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
770 rval = mb0 & MBS_MASK;
771 fw->risc_ram[cnt] = mb2;
772 } else {
773 rval = QLA_FUNCTION_FAILED;
774 }
775 }
776
777 if (rval != QLA_SUCCESS) {
778 qla_printk(KERN_WARNING, ha,
779 "Failed to dump firmware (%x)!!!\n", rval);
780
781 free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order);
782 ha->fw_dump = NULL;
783 } else {
784 qla_printk(KERN_INFO, ha,
785 "Firmware dump saved to temp buffer (%ld/%p).\n",
786 ha->host_no, ha->fw_dump);
787 }
788
789qla2100_fw_dump_failed:
790 if (!hardware_locked)
791 spin_unlock_irqrestore(&ha->hardware_lock, flags);
792}
793
794/**
795 * qla2100_ascii_fw_dump() - Converts a binary firmware dump to ASCII.
796 * @ha: HA context
797 */
798void
799qla2100_ascii_fw_dump(scsi_qla_host_t *ha)
800{
801 uint32_t cnt;
802 char *uiter;
803 char fw_info[30];
804 struct qla2100_fw_dump *fw;
805
806 uiter = ha->fw_dump_buffer;
807 fw = ha->fw_dump;
808
809 qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number,
Andrew Vasquezabbd8872005-07-06 10:30:05 -0700810 ha->isp_ops.fw_version_str(ha, fw_info));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
812 qla_uprintf(&uiter, "\n[==>BEG]\n");
813
814 qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr);
815
816 qla_uprintf(&uiter, "PBIU Registers:");
817 for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) {
818 if (cnt % 8 == 0) {
819 qla_uprintf(&uiter, "\n");
820 }
821 qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]);
822 }
823
824 qla_uprintf(&uiter, "\n\nMailbox Registers:");
825 for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
826 if (cnt % 8 == 0) {
827 qla_uprintf(&uiter, "\n");
828 }
829 qla_uprintf(&uiter, "%04x ", fw->mailbox_reg[cnt]);
830 }
831
832 qla_uprintf(&uiter, "\n\nDMA Registers:");
833 for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) {
834 if (cnt % 8 == 0) {
835 qla_uprintf(&uiter, "\n");
836 }
837 qla_uprintf(&uiter, "%04x ", fw->dma_reg[cnt]);
838 }
839
840 qla_uprintf(&uiter, "\n\nRISC Hardware Registers:");
841 for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) {
842 if (cnt % 8 == 0) {
843 qla_uprintf(&uiter, "\n");
844 }
845 qla_uprintf(&uiter, "%04x ", fw->risc_hdw_reg[cnt]);
846 }
847
848 qla_uprintf(&uiter, "\n\nRISC GP0 Registers:");
849 for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) {
850 if (cnt % 8 == 0) {
851 qla_uprintf(&uiter, "\n");
852 }
853 qla_uprintf(&uiter, "%04x ", fw->risc_gp0_reg[cnt]);
854 }
855
856 qla_uprintf(&uiter, "\n\nRISC GP1 Registers:");
857 for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) {
858 if (cnt % 8 == 0) {
859 qla_uprintf(&uiter, "\n");
860 }
861 qla_uprintf(&uiter, "%04x ", fw->risc_gp1_reg[cnt]);
862 }
863
864 qla_uprintf(&uiter, "\n\nRISC GP2 Registers:");
865 for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) {
866 if (cnt % 8 == 0) {
867 qla_uprintf(&uiter, "\n");
868 }
869 qla_uprintf(&uiter, "%04x ", fw->risc_gp2_reg[cnt]);
870 }
871
872 qla_uprintf(&uiter, "\n\nRISC GP3 Registers:");
873 for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) {
874 if (cnt % 8 == 0) {
875 qla_uprintf(&uiter, "\n");
876 }
877 qla_uprintf(&uiter, "%04x ", fw->risc_gp3_reg[cnt]);
878 }
879
880 qla_uprintf(&uiter, "\n\nRISC GP4 Registers:");
881 for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) {
882 if (cnt % 8 == 0) {
883 qla_uprintf(&uiter, "\n");
884 }
885 qla_uprintf(&uiter, "%04x ", fw->risc_gp4_reg[cnt]);
886 }
887
888 qla_uprintf(&uiter, "\n\nRISC GP5 Registers:");
889 for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) {
890 if (cnt % 8 == 0) {
891 qla_uprintf(&uiter, "\n");
892 }
893 qla_uprintf(&uiter, "%04x ", fw->risc_gp5_reg[cnt]);
894 }
895
896 qla_uprintf(&uiter, "\n\nRISC GP6 Registers:");
897 for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) {
898 if (cnt % 8 == 0) {
899 qla_uprintf(&uiter, "\n");
900 }
901 qla_uprintf(&uiter, "%04x ", fw->risc_gp6_reg[cnt]);
902 }
903
904 qla_uprintf(&uiter, "\n\nRISC GP7 Registers:");
905 for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) {
906 if (cnt % 8 == 0) {
907 qla_uprintf(&uiter, "\n");
908 }
909 qla_uprintf(&uiter, "%04x ", fw->risc_gp7_reg[cnt]);
910 }
911
912 qla_uprintf(&uiter, "\n\nFrame Buffer Hardware Registers:");
913 for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) {
914 if (cnt % 8 == 0) {
915 qla_uprintf(&uiter, "\n");
916 }
917 qla_uprintf(&uiter, "%04x ", fw->frame_buf_hdw_reg[cnt]);
918 }
919
920 qla_uprintf(&uiter, "\n\nFPM B0 Registers:");
921 for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) {
922 if (cnt % 8 == 0) {
923 qla_uprintf(&uiter, "\n");
924 }
925 qla_uprintf(&uiter, "%04x ", fw->fpm_b0_reg[cnt]);
926 }
927
928 qla_uprintf(&uiter, "\n\nFPM B1 Registers:");
929 for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) {
930 if (cnt % 8 == 0) {
931 qla_uprintf(&uiter, "\n");
932 }
933 qla_uprintf(&uiter, "%04x ", fw->fpm_b1_reg[cnt]);
934 }
935
936 qla_uprintf(&uiter, "\n\nRISC SRAM:");
937 for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) {
938 if (cnt % 8 == 0) {
939 qla_uprintf(&uiter, "\n%04x: ", cnt + 0x1000);
940 }
941 qla_uprintf(&uiter, "%04x ", fw->risc_ram[cnt]);
942 }
943
944 qla_uprintf(&uiter, "\n\n[<==END] ISP Debug Dump.");
945
946 return;
947}
948
949static int
950qla_uprintf(char **uiter, char *fmt, ...)
951{
952 int iter, len;
953 char buf[128];
954 va_list args;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700955
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 va_start(args, fmt);
957 len = vsprintf(buf, fmt, args);
958 va_end(args);
959
960 for (iter = 0; iter < len; iter++, *uiter += 1)
961 *uiter[0] = buf[iter];
962
963 return (len);
964}
965
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700966
967void
968qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
969{
970 int rval;
971 uint32_t cnt, timer;
972 uint32_t risc_address;
Andrew Vasquez335a1cc2005-11-08 14:37:48 -0800973 uint16_t mb[4], wd;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700974
975 uint32_t stat;
976 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
977 uint32_t __iomem *dmp_reg;
978 uint32_t *iter_reg;
979 uint16_t __iomem *mbx_reg;
980 unsigned long flags;
981 struct qla24xx_fw_dump *fw;
982 uint32_t ext_mem_cnt;
983
984 risc_address = ext_mem_cnt = 0;
985 memset(mb, 0, sizeof(mb));
986 flags = 0;
987
988 if (!hardware_locked)
989 spin_lock_irqsave(&ha->hardware_lock, flags);
990
991 if (!ha->fw_dump24) {
992 qla_printk(KERN_WARNING, ha,
993 "No buffer available for dump!!!\n");
994 goto qla24xx_fw_dump_failed;
995 }
996
997 if (ha->fw_dumped) {
998 qla_printk(KERN_WARNING, ha,
999 "Firmware has been previously dumped (%p) -- ignoring "
1000 "request...\n", ha->fw_dump24);
1001 goto qla24xx_fw_dump_failed;
1002 }
1003 fw = (struct qla24xx_fw_dump *) ha->fw_dump24;
1004
1005 rval = QLA_SUCCESS;
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001006 fw->host_status = RD_REG_DWORD(&reg->host_status);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001007
1008 /* Pause RISC. */
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001009 if ((RD_REG_DWORD(&reg->hccr) & HCCRX_RISC_PAUSE) == 0) {
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001010 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET |
1011 HCCRX_CLR_HOST_INT);
1012 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
1013 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
1014 for (cnt = 30000;
1015 (RD_REG_DWORD(&reg->hccr) & HCCRX_RISC_PAUSE) == 0 &&
1016 rval == QLA_SUCCESS; cnt--) {
1017 if (cnt)
1018 udelay(100);
1019 else
1020 rval = QLA_FUNCTION_TIMEOUT;
1021 }
1022 }
1023
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001024 if (rval == QLA_SUCCESS) {
1025 /* Host interface registers. */
1026 dmp_reg = (uint32_t __iomem *)(reg + 0);
1027 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
1028 fw->host_reg[cnt] = RD_REG_DWORD(dmp_reg++);
1029
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001030 /* Disable interrupts. */
1031 WRT_REG_DWORD(&reg->ictrl, 0);
1032 RD_REG_DWORD(&reg->ictrl);
1033
1034 /* Shadow registers. */
1035 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1036 RD_REG_DWORD(&reg->iobase_addr);
1037 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
1038 WRT_REG_DWORD(dmp_reg, 0xB0000000);
1039 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
1040 fw->shadow_reg[0] = RD_REG_DWORD(dmp_reg);
1041
1042 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
1043 WRT_REG_DWORD(dmp_reg, 0xB0100000);
1044 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
1045 fw->shadow_reg[1] = RD_REG_DWORD(dmp_reg);
1046
1047 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
1048 WRT_REG_DWORD(dmp_reg, 0xB0200000);
1049 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
1050 fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg);
1051
1052 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
1053 WRT_REG_DWORD(dmp_reg, 0xB0300000);
1054 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
1055 fw->shadow_reg[3] = RD_REG_DWORD(dmp_reg);
1056
1057 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
1058 WRT_REG_DWORD(dmp_reg, 0xB0400000);
1059 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
1060 fw->shadow_reg[4] = RD_REG_DWORD(dmp_reg);
1061
1062 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
1063 WRT_REG_DWORD(dmp_reg, 0xB0500000);
1064 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
1065 fw->shadow_reg[5] = RD_REG_DWORD(dmp_reg);
1066
1067 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
1068 WRT_REG_DWORD(dmp_reg, 0xB0600000);
1069 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
1070 fw->shadow_reg[6] = RD_REG_DWORD(dmp_reg);
1071
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001072 /* Mailbox registers. */
1073 mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
1074 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
1075 fw->mailbox_reg[cnt] = RD_REG_WORD(mbx_reg++);
1076
1077 /* Transfer sequence registers. */
1078 iter_reg = fw->xseq_gp_reg;
1079 WRT_REG_DWORD(&reg->iobase_addr, 0xBF00);
1080 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1081 for (cnt = 0; cnt < 16; cnt++)
1082 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1083
1084 WRT_REG_DWORD(&reg->iobase_addr, 0xBF10);
1085 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1086 for (cnt = 0; cnt < 16; cnt++)
1087 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1088
1089 WRT_REG_DWORD(&reg->iobase_addr, 0xBF20);
1090 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1091 for (cnt = 0; cnt < 16; cnt++)
1092 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1093
1094 WRT_REG_DWORD(&reg->iobase_addr, 0xBF30);
1095 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1096 for (cnt = 0; cnt < 16; cnt++)
1097 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1098
1099 WRT_REG_DWORD(&reg->iobase_addr, 0xBF40);
1100 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1101 for (cnt = 0; cnt < 16; cnt++)
1102 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1103
1104 WRT_REG_DWORD(&reg->iobase_addr, 0xBF50);
1105 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1106 for (cnt = 0; cnt < 16; cnt++)
1107 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1108
1109 WRT_REG_DWORD(&reg->iobase_addr, 0xBF60);
1110 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1111 for (cnt = 0; cnt < 16; cnt++)
1112 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1113
1114 WRT_REG_DWORD(&reg->iobase_addr, 0xBF70);
1115 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1116 for (cnt = 0; cnt < 16; cnt++)
1117 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1118
1119 WRT_REG_DWORD(&reg->iobase_addr, 0xBFE0);
1120 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1121 for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++)
1122 fw->xseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++);
1123
1124 WRT_REG_DWORD(&reg->iobase_addr, 0xBFF0);
1125 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1126 for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++)
1127 fw->xseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++);
1128
1129 /* Receive sequence registers. */
1130 iter_reg = fw->rseq_gp_reg;
1131 WRT_REG_DWORD(&reg->iobase_addr, 0xFF00);
1132 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1133 for (cnt = 0; cnt < 16; cnt++)
1134 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1135
1136 WRT_REG_DWORD(&reg->iobase_addr, 0xFF10);
1137 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1138 for (cnt = 0; cnt < 16; cnt++)
1139 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1140
1141 WRT_REG_DWORD(&reg->iobase_addr, 0xFF20);
1142 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1143 for (cnt = 0; cnt < 16; cnt++)
1144 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1145
1146 WRT_REG_DWORD(&reg->iobase_addr, 0xFF30);
1147 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1148 for (cnt = 0; cnt < 16; cnt++)
1149 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1150
1151 WRT_REG_DWORD(&reg->iobase_addr, 0xFF40);
1152 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1153 for (cnt = 0; cnt < 16; cnt++)
1154 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1155
1156 WRT_REG_DWORD(&reg->iobase_addr, 0xFF50);
1157 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1158 for (cnt = 0; cnt < 16; cnt++)
1159 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1160
1161 WRT_REG_DWORD(&reg->iobase_addr, 0xFF60);
1162 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1163 for (cnt = 0; cnt < 16; cnt++)
1164 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1165
1166 WRT_REG_DWORD(&reg->iobase_addr, 0xFF70);
1167 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1168 for (cnt = 0; cnt < 16; cnt++)
1169 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1170
1171 WRT_REG_DWORD(&reg->iobase_addr, 0xFFD0);
1172 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1173 for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++)
1174 fw->rseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++);
1175
1176 WRT_REG_DWORD(&reg->iobase_addr, 0xFFE0);
1177 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1178 for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++)
1179 fw->rseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++);
1180
1181 WRT_REG_DWORD(&reg->iobase_addr, 0xFFF0);
1182 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1183 for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++)
1184 fw->rseq_2_reg[cnt] = RD_REG_DWORD(dmp_reg++);
1185
1186 /* Command DMA registers. */
1187 WRT_REG_DWORD(&reg->iobase_addr, 0x7100);
1188 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1189 for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++)
1190 fw->cmd_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++);
1191
1192 /* Queues. */
1193 iter_reg = fw->req0_dma_reg;
1194 WRT_REG_DWORD(&reg->iobase_addr, 0x7200);
1195 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1196 for (cnt = 0; cnt < 8; cnt++)
1197 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1198
1199 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
1200 for (cnt = 0; cnt < 7; cnt++)
1201 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1202
1203 iter_reg = fw->resp0_dma_reg;
1204 WRT_REG_DWORD(&reg->iobase_addr, 0x7300);
1205 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1206 for (cnt = 0; cnt < 8; cnt++)
1207 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1208
1209 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
1210 for (cnt = 0; cnt < 7; cnt++)
1211 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1212
1213 iter_reg = fw->req1_dma_reg;
1214 WRT_REG_DWORD(&reg->iobase_addr, 0x7400);
1215 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1216 for (cnt = 0; cnt < 8; cnt++)
1217 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1218
1219 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
1220 for (cnt = 0; cnt < 7; cnt++)
1221 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1222
1223 /* Transmit DMA registers. */
1224 iter_reg = fw->xmt0_dma_reg;
1225 WRT_REG_DWORD(&reg->iobase_addr, 0x7600);
1226 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1227 for (cnt = 0; cnt < 16; cnt++)
1228 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1229
1230 WRT_REG_DWORD(&reg->iobase_addr, 0x7610);
1231 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1232 for (cnt = 0; cnt < 16; cnt++)
1233 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1234
1235 iter_reg = fw->xmt1_dma_reg;
1236 WRT_REG_DWORD(&reg->iobase_addr, 0x7620);
1237 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1238 for (cnt = 0; cnt < 16; cnt++)
1239 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1240
1241 WRT_REG_DWORD(&reg->iobase_addr, 0x7630);
1242 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1243 for (cnt = 0; cnt < 16; cnt++)
1244 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1245
1246 iter_reg = fw->xmt2_dma_reg;
1247 WRT_REG_DWORD(&reg->iobase_addr, 0x7640);
1248 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1249 for (cnt = 0; cnt < 16; cnt++)
1250 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1251
1252 WRT_REG_DWORD(&reg->iobase_addr, 0x7650);
1253 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1254 for (cnt = 0; cnt < 16; cnt++)
1255 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1256
1257 iter_reg = fw->xmt3_dma_reg;
1258 WRT_REG_DWORD(&reg->iobase_addr, 0x7660);
1259 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1260 for (cnt = 0; cnt < 16; cnt++)
1261 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1262
1263 WRT_REG_DWORD(&reg->iobase_addr, 0x7670);
1264 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1265 for (cnt = 0; cnt < 16; cnt++)
1266 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1267
1268 iter_reg = fw->xmt4_dma_reg;
1269 WRT_REG_DWORD(&reg->iobase_addr, 0x7680);
1270 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1271 for (cnt = 0; cnt < 16; cnt++)
1272 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1273
1274 WRT_REG_DWORD(&reg->iobase_addr, 0x7690);
1275 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1276 for (cnt = 0; cnt < 16; cnt++)
1277 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1278
1279 WRT_REG_DWORD(&reg->iobase_addr, 0x76A0);
1280 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1281 for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++)
1282 fw->xmt_data_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++);
1283
1284 /* Receive DMA registers. */
1285 iter_reg = fw->rcvt0_data_dma_reg;
1286 WRT_REG_DWORD(&reg->iobase_addr, 0x7700);
1287 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1288 for (cnt = 0; cnt < 16; cnt++)
1289 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1290
1291 WRT_REG_DWORD(&reg->iobase_addr, 0x7710);
1292 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1293 for (cnt = 0; cnt < 16; cnt++)
1294 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1295
1296 iter_reg = fw->rcvt1_data_dma_reg;
1297 WRT_REG_DWORD(&reg->iobase_addr, 0x7720);
1298 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1299 for (cnt = 0; cnt < 16; cnt++)
1300 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1301
1302 WRT_REG_DWORD(&reg->iobase_addr, 0x7730);
1303 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1304 for (cnt = 0; cnt < 16; cnt++)
1305 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1306
1307 /* RISC registers. */
1308 iter_reg = fw->risc_gp_reg;
1309 WRT_REG_DWORD(&reg->iobase_addr, 0x0F00);
1310 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1311 for (cnt = 0; cnt < 16; cnt++)
1312 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1313
1314 WRT_REG_DWORD(&reg->iobase_addr, 0x0F10);
1315 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1316 for (cnt = 0; cnt < 16; cnt++)
1317 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1318
1319 WRT_REG_DWORD(&reg->iobase_addr, 0x0F20);
1320 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1321 for (cnt = 0; cnt < 16; cnt++)
1322 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1323
1324 WRT_REG_DWORD(&reg->iobase_addr, 0x0F30);
1325 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1326 for (cnt = 0; cnt < 16; cnt++)
1327 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1328
1329 WRT_REG_DWORD(&reg->iobase_addr, 0x0F40);
1330 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1331 for (cnt = 0; cnt < 16; cnt++)
1332 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1333
1334 WRT_REG_DWORD(&reg->iobase_addr, 0x0F50);
1335 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1336 for (cnt = 0; cnt < 16; cnt++)
1337 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1338
1339 WRT_REG_DWORD(&reg->iobase_addr, 0x0F60);
1340 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1341 for (cnt = 0; cnt < 16; cnt++)
1342 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1343
1344 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1345 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1346 for (cnt = 0; cnt < 16; cnt++)
1347 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1348
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001349 /* Local memory controller registers. */
1350 iter_reg = fw->lmc_reg;
1351 WRT_REG_DWORD(&reg->iobase_addr, 0x3000);
1352 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1353 for (cnt = 0; cnt < 16; cnt++)
1354 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1355
1356 WRT_REG_DWORD(&reg->iobase_addr, 0x3010);
1357 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1358 for (cnt = 0; cnt < 16; cnt++)
1359 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1360
1361 WRT_REG_DWORD(&reg->iobase_addr, 0x3020);
1362 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1363 for (cnt = 0; cnt < 16; cnt++)
1364 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1365
1366 WRT_REG_DWORD(&reg->iobase_addr, 0x3030);
1367 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1368 for (cnt = 0; cnt < 16; cnt++)
1369 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1370
1371 WRT_REG_DWORD(&reg->iobase_addr, 0x3040);
1372 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1373 for (cnt = 0; cnt < 16; cnt++)
1374 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1375
1376 WRT_REG_DWORD(&reg->iobase_addr, 0x3050);
1377 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1378 for (cnt = 0; cnt < 16; cnt++)
1379 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1380
1381 WRT_REG_DWORD(&reg->iobase_addr, 0x3060);
1382 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1383 for (cnt = 0; cnt < 16; cnt++)
1384 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1385
1386 /* Fibre Protocol Module registers. */
1387 iter_reg = fw->fpm_hdw_reg;
1388 WRT_REG_DWORD(&reg->iobase_addr, 0x4000);
1389 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1390 for (cnt = 0; cnt < 16; cnt++)
1391 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1392
1393 WRT_REG_DWORD(&reg->iobase_addr, 0x4010);
1394 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1395 for (cnt = 0; cnt < 16; cnt++)
1396 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1397
1398 WRT_REG_DWORD(&reg->iobase_addr, 0x4020);
1399 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1400 for (cnt = 0; cnt < 16; cnt++)
1401 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1402
1403 WRT_REG_DWORD(&reg->iobase_addr, 0x4030);
1404 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1405 for (cnt = 0; cnt < 16; cnt++)
1406 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1407
1408 WRT_REG_DWORD(&reg->iobase_addr, 0x4040);
1409 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1410 for (cnt = 0; cnt < 16; cnt++)
1411 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1412
1413 WRT_REG_DWORD(&reg->iobase_addr, 0x4050);
1414 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1415 for (cnt = 0; cnt < 16; cnt++)
1416 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1417
1418 WRT_REG_DWORD(&reg->iobase_addr, 0x4060);
1419 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1420 for (cnt = 0; cnt < 16; cnt++)
1421 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1422
1423 WRT_REG_DWORD(&reg->iobase_addr, 0x4070);
1424 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1425 for (cnt = 0; cnt < 16; cnt++)
1426 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1427
1428 WRT_REG_DWORD(&reg->iobase_addr, 0x4080);
1429 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1430 for (cnt = 0; cnt < 16; cnt++)
1431 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1432
1433 WRT_REG_DWORD(&reg->iobase_addr, 0x4090);
1434 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1435 for (cnt = 0; cnt < 16; cnt++)
1436 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1437
1438 WRT_REG_DWORD(&reg->iobase_addr, 0x40A0);
1439 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1440 for (cnt = 0; cnt < 16; cnt++)
1441 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1442
1443 WRT_REG_DWORD(&reg->iobase_addr, 0x40B0);
1444 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1445 for (cnt = 0; cnt < 16; cnt++)
1446 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1447
1448 /* Frame Buffer registers. */
1449 iter_reg = fw->fb_hdw_reg;
1450 WRT_REG_DWORD(&reg->iobase_addr, 0x6000);
1451 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1452 for (cnt = 0; cnt < 16; cnt++)
1453 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1454
1455 WRT_REG_DWORD(&reg->iobase_addr, 0x6010);
1456 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1457 for (cnt = 0; cnt < 16; cnt++)
1458 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1459
1460 WRT_REG_DWORD(&reg->iobase_addr, 0x6020);
1461 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1462 for (cnt = 0; cnt < 16; cnt++)
1463 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1464
1465 WRT_REG_DWORD(&reg->iobase_addr, 0x6030);
1466 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1467 for (cnt = 0; cnt < 16; cnt++)
1468 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1469
1470 WRT_REG_DWORD(&reg->iobase_addr, 0x6040);
1471 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1472 for (cnt = 0; cnt < 16; cnt++)
1473 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1474
1475 WRT_REG_DWORD(&reg->iobase_addr, 0x6100);
1476 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1477 for (cnt = 0; cnt < 16; cnt++)
1478 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1479
1480 WRT_REG_DWORD(&reg->iobase_addr, 0x6130);
1481 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1482 for (cnt = 0; cnt < 16; cnt++)
1483 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1484
1485 WRT_REG_DWORD(&reg->iobase_addr, 0x6150);
1486 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1487 for (cnt = 0; cnt < 16; cnt++)
1488 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1489
1490 WRT_REG_DWORD(&reg->iobase_addr, 0x6170);
1491 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1492 for (cnt = 0; cnt < 16; cnt++)
1493 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1494
1495 WRT_REG_DWORD(&reg->iobase_addr, 0x6190);
1496 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1497 for (cnt = 0; cnt < 16; cnt++)
1498 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1499
1500 WRT_REG_DWORD(&reg->iobase_addr, 0x61B0);
1501 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1502 for (cnt = 0; cnt < 16; cnt++)
1503 *iter_reg++ = RD_REG_DWORD(dmp_reg++);
1504
1505 /* Reset RISC. */
1506 WRT_REG_DWORD(&reg->ctrl_status,
1507 CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
1508 for (cnt = 0; cnt < 30000; cnt++) {
1509 if ((RD_REG_DWORD(&reg->ctrl_status) &
1510 CSRX_DMA_ACTIVE) == 0)
1511 break;
1512
1513 udelay(10);
1514 }
1515
1516 WRT_REG_DWORD(&reg->ctrl_status,
1517 CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
Andrew Vasquez335a1cc2005-11-08 14:37:48 -08001518 pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
Andrew Vasquez88c26662005-07-08 17:59:26 -07001519
Andrew Vasquez335a1cc2005-11-08 14:37:48 -08001520 udelay(100);
Andrew Vasquez88c26662005-07-08 17:59:26 -07001521 /* Wait for firmware to complete NVRAM accesses. */
Andrew Vasquez88c26662005-07-08 17:59:26 -07001522 mb[0] = (uint32_t) RD_REG_WORD(&reg->mailbox0);
1523 for (cnt = 10000 ; cnt && mb[0]; cnt--) {
1524 udelay(5);
1525 mb[0] = (uint32_t) RD_REG_WORD(&reg->mailbox0);
1526 barrier();
1527 }
1528
Andrew Vasquez335a1cc2005-11-08 14:37:48 -08001529 /* Wait for soft-reset to complete. */
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001530 for (cnt = 0; cnt < 30000; cnt++) {
1531 if ((RD_REG_DWORD(&reg->ctrl_status) &
1532 CSRX_ISP_SOFT_RESET) == 0)
1533 break;
1534
1535 udelay(10);
1536 }
1537 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
1538 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
1539 }
1540
1541 for (cnt = 30000; RD_REG_WORD(&reg->mailbox0) != 0 &&
1542 rval == QLA_SUCCESS; cnt--) {
1543 if (cnt)
1544 udelay(100);
1545 else
1546 rval = QLA_FUNCTION_TIMEOUT;
1547 }
1548
1549 /* Memory. */
1550 if (rval == QLA_SUCCESS) {
1551 /* Code RAM. */
1552 risc_address = 0x20000;
1553 WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);
1554 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1555 }
1556 for (cnt = 0; cnt < sizeof(fw->code_ram) / 4 && rval == QLA_SUCCESS;
1557 cnt++, risc_address++) {
1558 WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));
1559 WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));
1560 RD_REG_WORD(&reg->mailbox8);
1561 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
1562
1563 for (timer = 6000000; timer; timer--) {
1564 /* Check for pending interrupts. */
1565 stat = RD_REG_DWORD(&reg->host_status);
1566 if (stat & HSRX_RISC_INT) {
1567 stat &= 0xff;
1568
1569 if (stat == 0x1 || stat == 0x2 ||
1570 stat == 0x10 || stat == 0x11) {
1571 set_bit(MBX_INTERRUPT,
1572 &ha->mbx_cmd_flags);
1573
1574 mb[0] = RD_REG_WORD(&reg->mailbox0);
1575 mb[2] = RD_REG_WORD(&reg->mailbox2);
1576 mb[3] = RD_REG_WORD(&reg->mailbox3);
1577
1578 WRT_REG_DWORD(&reg->hccr,
1579 HCCRX_CLR_RISC_INT);
1580 RD_REG_DWORD(&reg->hccr);
1581 break;
1582 }
1583
1584 /* Clear this intr; it wasn't a mailbox intr */
1585 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1586 RD_REG_DWORD(&reg->hccr);
1587 }
1588 udelay(5);
1589 }
1590
1591 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
1592 rval = mb[0] & MBS_MASK;
1593 fw->code_ram[cnt] = (mb[3] << 16) | mb[2];
1594 } else {
1595 rval = QLA_FUNCTION_FAILED;
1596 }
1597 }
1598
1599 if (rval == QLA_SUCCESS) {
1600 /* External Memory. */
1601 risc_address = 0x100000;
1602 ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1;
1603 WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);
1604 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1605 }
1606 for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS;
1607 cnt++, risc_address++) {
1608 WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));
1609 WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));
1610 RD_REG_WORD(&reg->mailbox8);
1611 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
1612
1613 for (timer = 6000000; timer; timer--) {
1614 /* Check for pending interrupts. */
1615 stat = RD_REG_DWORD(&reg->host_status);
1616 if (stat & HSRX_RISC_INT) {
1617 stat &= 0xff;
1618
1619 if (stat == 0x1 || stat == 0x2 ||
1620 stat == 0x10 || stat == 0x11) {
1621 set_bit(MBX_INTERRUPT,
1622 &ha->mbx_cmd_flags);
1623
1624 mb[0] = RD_REG_WORD(&reg->mailbox0);
1625 mb[2] = RD_REG_WORD(&reg->mailbox2);
1626 mb[3] = RD_REG_WORD(&reg->mailbox3);
1627
1628 WRT_REG_DWORD(&reg->hccr,
1629 HCCRX_CLR_RISC_INT);
1630 RD_REG_DWORD(&reg->hccr);
1631 break;
1632 }
1633
1634 /* Clear this intr; it wasn't a mailbox intr */
1635 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1636 RD_REG_DWORD(&reg->hccr);
1637 }
1638 udelay(5);
1639 }
1640
1641 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
1642 rval = mb[0] & MBS_MASK;
1643 fw->ext_mem[cnt] = (mb[3] << 16) | mb[2];
1644 } else {
1645 rval = QLA_FUNCTION_FAILED;
1646 }
1647 }
1648
1649 if (rval != QLA_SUCCESS) {
1650 qla_printk(KERN_WARNING, ha,
1651 "Failed to dump firmware (%x)!!!\n", rval);
1652 ha->fw_dumped = 0;
1653
1654 } else {
1655 qla_printk(KERN_INFO, ha,
1656 "Firmware dump saved to temp buffer (%ld/%p).\n",
1657 ha->host_no, ha->fw_dump24);
1658 ha->fw_dumped = 1;
1659 }
1660
1661qla24xx_fw_dump_failed:
1662 if (!hardware_locked)
1663 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1664}
1665
1666void
1667qla24xx_ascii_fw_dump(scsi_qla_host_t *ha)
1668{
1669 uint32_t cnt;
1670 char *uiter;
1671 struct qla24xx_fw_dump *fw;
1672 uint32_t ext_mem_cnt;
1673
1674 uiter = ha->fw_dump_buffer;
1675 fw = ha->fw_dump24;
1676
1677 qla_uprintf(&uiter, "ISP FW Version %d.%02d.%02d Attributes %04x\n",
1678 ha->fw_major_version, ha->fw_minor_version,
1679 ha->fw_subminor_version, ha->fw_attributes);
1680
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001681 qla_uprintf(&uiter, "\nR2H Status Register\n%04x\n", fw->host_status);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001682
1683 qla_uprintf(&uiter, "\nHost Interface Registers");
1684 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) {
1685 if (cnt % 8 == 0)
1686 qla_uprintf(&uiter, "\n");
1687
1688 qla_uprintf(&uiter, "%08x ", fw->host_reg[cnt]);
1689 }
1690
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001691 qla_uprintf(&uiter, "\n\nShadow Registers");
1692 for (cnt = 0; cnt < sizeof(fw->shadow_reg) / 4; cnt++) {
1693 if (cnt % 8 == 0)
1694 qla_uprintf(&uiter, "\n");
1695
1696 qla_uprintf(&uiter, "%08x ", fw->shadow_reg[cnt]);
1697 }
1698
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001699 qla_uprintf(&uiter, "\n\nMailbox Registers");
1700 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) {
1701 if (cnt % 8 == 0)
1702 qla_uprintf(&uiter, "\n");
1703
1704 qla_uprintf(&uiter, "%08x ", fw->mailbox_reg[cnt]);
1705 }
1706
1707 qla_uprintf(&uiter, "\n\nXSEQ GP Registers");
1708 for (cnt = 0; cnt < sizeof(fw->xseq_gp_reg) / 4; cnt++) {
1709 if (cnt % 8 == 0)
1710 qla_uprintf(&uiter, "\n");
1711
1712 qla_uprintf(&uiter, "%08x ", fw->xseq_gp_reg[cnt]);
1713 }
1714
1715 qla_uprintf(&uiter, "\n\nXSEQ-0 Registers");
1716 for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) {
1717 if (cnt % 8 == 0)
1718 qla_uprintf(&uiter, "\n");
1719
1720 qla_uprintf(&uiter, "%08x ", fw->xseq_0_reg[cnt]);
1721 }
1722
1723 qla_uprintf(&uiter, "\n\nXSEQ-1 Registers");
1724 for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) {
1725 if (cnt % 8 == 0)
1726 qla_uprintf(&uiter, "\n");
1727
1728 qla_uprintf(&uiter, "%08x ", fw->xseq_1_reg[cnt]);
1729 }
1730
1731 qla_uprintf(&uiter, "\n\nRSEQ GP Registers");
1732 for (cnt = 0; cnt < sizeof(fw->rseq_gp_reg) / 4; cnt++) {
1733 if (cnt % 8 == 0)
1734 qla_uprintf(&uiter, "\n");
1735
1736 qla_uprintf(&uiter, "%08x ", fw->rseq_gp_reg[cnt]);
1737 }
1738
1739 qla_uprintf(&uiter, "\n\nRSEQ-0 Registers");
1740 for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) {
1741 if (cnt % 8 == 0)
1742 qla_uprintf(&uiter, "\n");
1743
1744 qla_uprintf(&uiter, "%08x ", fw->rseq_0_reg[cnt]);
1745 }
1746
1747 qla_uprintf(&uiter, "\n\nRSEQ-1 Registers");
1748 for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) {
1749 if (cnt % 8 == 0)
1750 qla_uprintf(&uiter, "\n");
1751
1752 qla_uprintf(&uiter, "%08x ", fw->rseq_1_reg[cnt]);
1753 }
1754
1755 qla_uprintf(&uiter, "\n\nRSEQ-2 Registers");
1756 for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) {
1757 if (cnt % 8 == 0)
1758 qla_uprintf(&uiter, "\n");
1759
1760 qla_uprintf(&uiter, "%08x ", fw->rseq_2_reg[cnt]);
1761 }
1762
1763 qla_uprintf(&uiter, "\n\nCommand DMA Registers");
1764 for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) {
1765 if (cnt % 8 == 0)
1766 qla_uprintf(&uiter, "\n");
1767
1768 qla_uprintf(&uiter, "%08x ", fw->cmd_dma_reg[cnt]);
1769 }
1770
1771 qla_uprintf(&uiter, "\n\nRequest0 Queue DMA Channel Registers");
1772 for (cnt = 0; cnt < sizeof(fw->req0_dma_reg) / 4; cnt++) {
1773 if (cnt % 8 == 0)
1774 qla_uprintf(&uiter, "\n");
1775
1776 qla_uprintf(&uiter, "%08x ", fw->req0_dma_reg[cnt]);
1777 }
1778
1779 qla_uprintf(&uiter, "\n\nResponse0 Queue DMA Channel Registers");
1780 for (cnt = 0; cnt < sizeof(fw->resp0_dma_reg) / 4; cnt++) {
1781 if (cnt % 8 == 0)
1782 qla_uprintf(&uiter, "\n");
1783
1784 qla_uprintf(&uiter, "%08x ", fw->resp0_dma_reg[cnt]);
1785 }
1786
1787 qla_uprintf(&uiter, "\n\nRequest1 Queue DMA Channel Registers");
1788 for (cnt = 0; cnt < sizeof(fw->req1_dma_reg) / 4; cnt++) {
1789 if (cnt % 8 == 0)
1790 qla_uprintf(&uiter, "\n");
1791
1792 qla_uprintf(&uiter, "%08x ", fw->req1_dma_reg[cnt]);
1793 }
1794
1795 qla_uprintf(&uiter, "\n\nXMT0 Data DMA Registers");
1796 for (cnt = 0; cnt < sizeof(fw->xmt0_dma_reg) / 4; cnt++) {
1797 if (cnt % 8 == 0)
1798 qla_uprintf(&uiter, "\n");
1799
1800 qla_uprintf(&uiter, "%08x ", fw->xmt0_dma_reg[cnt]);
1801 }
1802
1803 qla_uprintf(&uiter, "\n\nXMT1 Data DMA Registers");
1804 for (cnt = 0; cnt < sizeof(fw->xmt1_dma_reg) / 4; cnt++) {
1805 if (cnt % 8 == 0)
1806 qla_uprintf(&uiter, "\n");
1807
1808 qla_uprintf(&uiter, "%08x ", fw->xmt1_dma_reg[cnt]);
1809 }
1810
1811 qla_uprintf(&uiter, "\n\nXMT2 Data DMA Registers");
1812 for (cnt = 0; cnt < sizeof(fw->xmt2_dma_reg) / 4; cnt++) {
1813 if (cnt % 8 == 0)
1814 qla_uprintf(&uiter, "\n");
1815
1816 qla_uprintf(&uiter, "%08x ", fw->xmt2_dma_reg[cnt]);
1817 }
1818
1819 qla_uprintf(&uiter, "\n\nXMT3 Data DMA Registers");
1820 for (cnt = 0; cnt < sizeof(fw->xmt3_dma_reg) / 4; cnt++) {
1821 if (cnt % 8 == 0)
1822 qla_uprintf(&uiter, "\n");
1823
1824 qla_uprintf(&uiter, "%08x ", fw->xmt3_dma_reg[cnt]);
1825 }
1826
1827 qla_uprintf(&uiter, "\n\nXMT4 Data DMA Registers");
1828 for (cnt = 0; cnt < sizeof(fw->xmt4_dma_reg) / 4; cnt++) {
1829 if (cnt % 8 == 0)
1830 qla_uprintf(&uiter, "\n");
1831
1832 qla_uprintf(&uiter, "%08x ", fw->xmt4_dma_reg[cnt]);
1833 }
1834
1835 qla_uprintf(&uiter, "\n\nXMT Data DMA Common Registers");
1836 for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) {
1837 if (cnt % 8 == 0)
1838 qla_uprintf(&uiter, "\n");
1839
1840 qla_uprintf(&uiter, "%08x ", fw->xmt_data_dma_reg[cnt]);
1841 }
1842
1843 qla_uprintf(&uiter, "\n\nRCV Thread 0 Data DMA Registers");
1844 for (cnt = 0; cnt < sizeof(fw->rcvt0_data_dma_reg) / 4; cnt++) {
1845 if (cnt % 8 == 0)
1846 qla_uprintf(&uiter, "\n");
1847
1848 qla_uprintf(&uiter, "%08x ", fw->rcvt0_data_dma_reg[cnt]);
1849 }
1850
1851 qla_uprintf(&uiter, "\n\nRCV Thread 1 Data DMA Registers");
1852 for (cnt = 0; cnt < sizeof(fw->rcvt1_data_dma_reg) / 4; cnt++) {
1853 if (cnt % 8 == 0)
1854 qla_uprintf(&uiter, "\n");
1855
1856 qla_uprintf(&uiter, "%08x ", fw->rcvt1_data_dma_reg[cnt]);
1857 }
1858
1859 qla_uprintf(&uiter, "\n\nRISC GP Registers");
1860 for (cnt = 0; cnt < sizeof(fw->risc_gp_reg) / 4; cnt++) {
1861 if (cnt % 8 == 0)
1862 qla_uprintf(&uiter, "\n");
1863
1864 qla_uprintf(&uiter, "%08x ", fw->risc_gp_reg[cnt]);
1865 }
1866
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001867 qla_uprintf(&uiter, "\n\nLMC Registers");
1868 for (cnt = 0; cnt < sizeof(fw->lmc_reg) / 4; cnt++) {
1869 if (cnt % 8 == 0)
1870 qla_uprintf(&uiter, "\n");
1871
1872 qla_uprintf(&uiter, "%08x ", fw->lmc_reg[cnt]);
1873 }
1874
1875 qla_uprintf(&uiter, "\n\nFPM Hardware Registers");
1876 for (cnt = 0; cnt < sizeof(fw->fpm_hdw_reg) / 4; cnt++) {
1877 if (cnt % 8 == 0)
1878 qla_uprintf(&uiter, "\n");
1879
1880 qla_uprintf(&uiter, "%08x ", fw->fpm_hdw_reg[cnt]);
1881 }
1882
1883 qla_uprintf(&uiter, "\n\nFB Hardware Registers");
1884 for (cnt = 0; cnt < sizeof(fw->fb_hdw_reg) / 4; cnt++) {
1885 if (cnt % 8 == 0)
1886 qla_uprintf(&uiter, "\n");
1887
1888 qla_uprintf(&uiter, "%08x ", fw->fb_hdw_reg[cnt]);
1889 }
1890
1891 qla_uprintf(&uiter, "\n\nCode RAM");
1892 for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
1893 if (cnt % 8 == 0) {
1894 qla_uprintf(&uiter, "\n%08x: ", cnt + 0x20000);
1895 }
1896 qla_uprintf(&uiter, "%08x ", fw->code_ram[cnt]);
1897 }
1898
1899 qla_uprintf(&uiter, "\n\nExternal Memory");
1900 ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1;
1901 for (cnt = 0; cnt < ext_mem_cnt; cnt++) {
1902 if (cnt % 8 == 0) {
1903 qla_uprintf(&uiter, "\n%08x: ", cnt + 0x100000);
1904 }
1905 qla_uprintf(&uiter, "%08x ", fw->ext_mem[cnt]);
1906 }
1907
1908 qla_uprintf(&uiter, "\n[<==END] ISP Debug Dump");
1909}
1910
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
1912/****************************************************************************/
1913/* Driver Debug Functions. */
1914/****************************************************************************/
1915
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001916void
1917qla2x00_dump_regs(scsi_qla_host_t *ha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918{
Andrew Vasquez3d716442005-07-06 10:30:26 -07001919 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920
1921 printk("Mailbox registers:\n");
1922 printk("scsi(%ld): mbox 0 0x%04x \n",
1923 ha->host_no, RD_MAILBOX_REG(ha, reg, 0));
1924 printk("scsi(%ld): mbox 1 0x%04x \n",
1925 ha->host_no, RD_MAILBOX_REG(ha, reg, 1));
1926 printk("scsi(%ld): mbox 2 0x%04x \n",
1927 ha->host_no, RD_MAILBOX_REG(ha, reg, 2));
1928 printk("scsi(%ld): mbox 3 0x%04x \n",
1929 ha->host_no, RD_MAILBOX_REG(ha, reg, 3));
1930 printk("scsi(%ld): mbox 4 0x%04x \n",
1931 ha->host_no, RD_MAILBOX_REG(ha, reg, 4));
1932 printk("scsi(%ld): mbox 5 0x%04x \n",
1933 ha->host_no, RD_MAILBOX_REG(ha, reg, 5));
1934}
1935
1936
1937void
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001938qla2x00_dump_buffer(uint8_t * b, uint32_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939{
1940 uint32_t cnt;
1941 uint8_t c;
1942
1943 printk(" 0 1 2 3 4 5 6 7 8 9 "
1944 "Ah Bh Ch Dh Eh Fh\n");
1945 printk("----------------------------------------"
1946 "----------------------\n");
1947
1948 for (cnt = 0; cnt < size;) {
1949 c = *b++;
1950 printk("%02x",(uint32_t) c);
1951 cnt++;
1952 if (!(cnt % 16))
1953 printk("\n");
1954 else
1955 printk(" ");
1956 }
1957 if (cnt % 16)
1958 printk("\n");
1959}
1960
1961/**************************************************************************
1962 * qla2x00_print_scsi_cmd
1963 * Dumps out info about the scsi cmd and srb.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001964 * Input
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 * cmd : struct scsi_cmnd
1966 **************************************************************************/
1967void
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001968qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969{
1970 int i;
1971 struct scsi_qla_host *ha;
1972 srb_t *sp;
1973
1974 ha = (struct scsi_qla_host *)cmd->device->host->hostdata;
1975
1976 sp = (srb_t *) cmd->SCp.ptr;
1977 printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble);
1978 printk(" chan=0x%02x, target=0x%02x, lun=0x%02x, cmd_len=0x%02x\n",
1979 cmd->device->channel, cmd->device->id, cmd->device->lun,
1980 cmd->cmd_len);
1981 printk(" CDB: ");
1982 for (i = 0; i < cmd->cmd_len; i++) {
1983 printk("0x%02x ", cmd->cmnd[i]);
1984 }
c6295cd2005-04-03 14:59:11 -05001985 printk("\n seg_cnt=%d, allowed=%d, retries=%d\n",
1986 cmd->use_sg, cmd->allowed, cmd->retries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987 printk(" request buffer=0x%p, request buffer len=0x%x\n",
1988 cmd->request_buffer, cmd->request_bufflen);
1989 printk(" tag=%d, transfersize=0x%x\n",
1990 cmd->tag, cmd->transfersize);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001991 printk(" serial_number=%lx, SP=%p\n", cmd->serial_number, sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992 printk(" data direction=%d\n", cmd->sc_data_direction);
1993
1994 if (!sp)
1995 return;
1996
1997 printk(" sp flags=0x%x\n", sp->flags);
Andrew Vasquez 354d6b22005-04-23 02:47:27 -04001998 printk(" state=%d\n", sp->state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999}
2000
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07002001void
2002qla2x00_dump_pkt(void *pkt)
2003{
2004 uint32_t i;
2005 uint8_t *data = (uint8_t *) pkt;
2006
2007 for (i = 0; i < 64; i++) {
2008 if (!(i % 4))
2009 printk("\n%02x: ", i);
2010
2011 printk("%02x ", data[i]);
2012 }
2013 printk("\n");
2014}
2015
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016#if defined(QL_DEBUG_ROUTINES)
2017/*
2018 * qla2x00_formatted_dump_buffer
2019 * Prints string plus buffer.
2020 *
2021 * Input:
2022 * string = Null terminated string (no newline at end).
2023 * buffer = buffer address.
2024 * wd_size = word size 8, 16, 32 or 64 bits
2025 * count = number of words.
2026 */
2027void
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002028qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer,
2029 uint8_t wd_size, uint32_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030{
2031 uint32_t cnt;
2032 uint16_t *buf16;
2033 uint32_t *buf32;
2034
2035 if (strcmp(string, "") != 0)
2036 printk("%s\n",string);
2037
2038 switch (wd_size) {
2039 case 8:
2040 printk(" 0 1 2 3 4 5 6 7 "
2041 "8 9 Ah Bh Ch Dh Eh Fh\n");
2042 printk("-----------------------------------------"
2043 "-------------------------------------\n");
2044
2045 for (cnt = 1; cnt <= count; cnt++, buffer++) {
2046 printk("%02x",*buffer);
2047 if (cnt % 16 == 0)
2048 printk("\n");
2049 else
2050 printk(" ");
2051 }
2052 if (cnt % 16 != 0)
2053 printk("\n");
2054 break;
2055 case 16:
2056 printk(" 0 2 4 6 8 Ah "
2057 " Ch Eh\n");
2058 printk("-----------------------------------------"
2059 "-------------\n");
2060
2061 buf16 = (uint16_t *) buffer;
2062 for (cnt = 1; cnt <= count; cnt++, buf16++) {
2063 printk("%4x",*buf16);
2064
2065 if (cnt % 8 == 0)
2066 printk("\n");
2067 else if (*buf16 < 10)
2068 printk(" ");
2069 else
2070 printk(" ");
2071 }
2072 if (cnt % 8 != 0)
2073 printk("\n");
2074 break;
2075 case 32:
2076 printk(" 0 4 8 Ch\n");
2077 printk("------------------------------------------\n");
2078
2079 buf32 = (uint32_t *) buffer;
2080 for (cnt = 1; cnt <= count; cnt++, buf32++) {
2081 printk("%8x", *buf32);
2082
2083 if (cnt % 4 == 0)
2084 printk("\n");
2085 else if (*buf32 < 10)
2086 printk(" ");
2087 else
2088 printk(" ");
2089 }
2090 if (cnt % 4 != 0)
2091 printk("\n");
2092 break;
2093 default:
2094 break;
2095 }
2096}
2097#endif