blob: f6ed6962bc2b71617b631d422e0221eb8c190488 [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
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070011static inline void
12qla2xxx_prep_dump(scsi_qla_host_t *ha, struct qla2xxx_fw_dump *fw_dump)
13{
14 fw_dump->fw_major_version = htonl(ha->fw_major_version);
15 fw_dump->fw_minor_version = htonl(ha->fw_minor_version);
16 fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version);
17 fw_dump->fw_attributes = htonl(ha->fw_attributes);
18
19 fw_dump->vendor = htonl(ha->pdev->vendor);
20 fw_dump->device = htonl(ha->pdev->device);
21 fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor);
22 fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device);
23}
24
25static inline void *
26qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr)
27{
28 /* Request queue. */
29 memcpy(ptr, ha->request_ring, ha->request_q_length *
30 sizeof(request_t));
31
32 /* Response queue. */
33 ptr += ha->request_q_length * sizeof(request_t);
34 memcpy(ptr, ha->response_ring, ha->response_q_length *
35 sizeof(response_t));
36
37 return ptr + (ha->response_q_length * sizeof(response_t));
38}
Linus Torvalds1da177e2005-04-16 15:20:36 -070039
40/**
41 * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
42 * @ha: HA context
43 * @hardware_locked: Called with the hardware_lock
44 */
45void
46qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
47{
48 int rval;
49 uint32_t cnt, timer;
50 uint32_t risc_address;
51 uint16_t mb0, mb2;
52
53 uint32_t stat;
Andrew Vasquez3d716442005-07-06 10:30:26 -070054 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 uint16_t __iomem *dmp_reg;
56 unsigned long flags;
57 struct qla2300_fw_dump *fw;
Andrew Vasquezd4e3e042006-05-17 15:09:50 -070058 uint32_t data_ram_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
60 risc_address = data_ram_cnt = 0;
61 mb0 = mb2 = 0;
62 flags = 0;
63
64 if (!hardware_locked)
65 spin_lock_irqsave(&ha->hardware_lock, flags);
66
Andrew Vasquezd4e3e042006-05-17 15:09:50 -070067 if (!ha->fw_dump) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 qla_printk(KERN_WARNING, ha,
Andrew Vasquezd4e3e042006-05-17 15:09:50 -070069 "No buffer available for dump!!!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 goto qla2300_fw_dump_failed;
71 }
72
Andrew Vasquezd4e3e042006-05-17 15:09:50 -070073 if (ha->fw_dumped) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 qla_printk(KERN_WARNING, ha,
Andrew Vasquezd4e3e042006-05-17 15:09:50 -070075 "Firmware has been previously dumped (%p) -- ignoring "
76 "request...\n", ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -070077 goto qla2300_fw_dump_failed;
78 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070079 fw = &ha->fw_dump->isp.isp23;
80 qla2xxx_prep_dump(ha, ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
82 rval = QLA_SUCCESS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070083 fw->hccr = htons(RD_REG_WORD(&reg->hccr));
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
85 /* Pause RISC. */
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -070086 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 if (IS_QLA2300(ha)) {
88 for (cnt = 30000;
89 (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
90 rval == QLA_SUCCESS; cnt--) {
91 if (cnt)
92 udelay(100);
93 else
94 rval = QLA_FUNCTION_TIMEOUT;
95 }
96 } else {
97 RD_REG_WORD(&reg->hccr); /* PCI Posting. */
98 udelay(10);
99 }
100
101 if (rval == QLA_SUCCESS) {
102 dmp_reg = (uint16_t __iomem *)(reg + 0);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700103 for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700104 fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
106 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700107 for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700108 fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
110 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700111 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700112 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
114 WRT_REG_WORD(&reg->ctrl_status, 0x40);
115 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700116 for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700117 fw->resp_dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
119 WRT_REG_WORD(&reg->ctrl_status, 0x50);
120 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700121 for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700122 fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
124 WRT_REG_WORD(&reg->ctrl_status, 0x00);
125 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700126 for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700127 fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700129 WRT_REG_WORD(&reg->pcr, 0x2000);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700131 for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700132 fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700134 WRT_REG_WORD(&reg->pcr, 0x2200);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700136 for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700137 fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700139 WRT_REG_WORD(&reg->pcr, 0x2400);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700141 for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700142 fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700144 WRT_REG_WORD(&reg->pcr, 0x2600);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700146 for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700147 fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700149 WRT_REG_WORD(&reg->pcr, 0x2800);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700151 for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700152 fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700154 WRT_REG_WORD(&reg->pcr, 0x2A00);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700156 for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700157 fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700159 WRT_REG_WORD(&reg->pcr, 0x2C00);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700161 for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700162 fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700164 WRT_REG_WORD(&reg->pcr, 0x2E00);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700166 for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700167 fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700169 WRT_REG_WORD(&reg->ctrl_status, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700171 for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700172 fw->frame_buf_hdw_reg[cnt] =
173 htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700175 WRT_REG_WORD(&reg->ctrl_status, 0x20);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700177 for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700178 fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700180 WRT_REG_WORD(&reg->ctrl_status, 0x30);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700182 for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700183 fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184
185 /* Reset RISC. */
186 WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
187 for (cnt = 0; cnt < 30000; cnt++) {
188 if ((RD_REG_WORD(&reg->ctrl_status) &
189 CSR_ISP_SOFT_RESET) == 0)
190 break;
191
192 udelay(10);
193 }
194 }
195
196 if (!IS_QLA2300(ha)) {
197 for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
198 rval == QLA_SUCCESS; cnt--) {
199 if (cnt)
200 udelay(100);
201 else
202 rval = QLA_FUNCTION_TIMEOUT;
203 }
204 }
205
206 if (rval == QLA_SUCCESS) {
207 /* Get RISC SRAM. */
208 risc_address = 0x800;
209 WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
210 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
211 }
212 for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;
213 cnt++, risc_address++) {
214 WRT_MAILBOX_REG(ha, reg, 1, (uint16_t)risc_address);
215 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
216
217 for (timer = 6000000; timer; timer--) {
218 /* Check for pending interrupts. */
219 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
220 if (stat & HSR_RISC_INT) {
221 stat &= 0xff;
222
223 if (stat == 0x1 || stat == 0x2) {
224 set_bit(MBX_INTERRUPT,
225 &ha->mbx_cmd_flags);
226
227 mb0 = RD_MAILBOX_REG(ha, reg, 0);
228 mb2 = RD_MAILBOX_REG(ha, reg, 2);
229
230 /* Release mailbox registers. */
231 WRT_REG_WORD(&reg->semaphore, 0);
232 WRT_REG_WORD(&reg->hccr,
233 HCCR_CLR_RISC_INT);
234 RD_REG_WORD(&reg->hccr);
235 break;
236 } else if (stat == 0x10 || stat == 0x11) {
237 set_bit(MBX_INTERRUPT,
238 &ha->mbx_cmd_flags);
239
240 mb0 = RD_MAILBOX_REG(ha, reg, 0);
241 mb2 = RD_MAILBOX_REG(ha, reg, 2);
242
243 WRT_REG_WORD(&reg->hccr,
244 HCCR_CLR_RISC_INT);
245 RD_REG_WORD(&reg->hccr);
246 break;
247 }
248
249 /* clear this intr; it wasn't a mailbox intr */
250 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
251 RD_REG_WORD(&reg->hccr);
252 }
253 udelay(5);
254 }
255
256 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
257 rval = mb0 & MBS_MASK;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700258 fw->risc_ram[cnt] = htons(mb2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 } else {
260 rval = QLA_FUNCTION_FAILED;
261 }
262 }
263
264 if (rval == QLA_SUCCESS) {
265 /* Get stack SRAM. */
266 risc_address = 0x10000;
267 WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED);
268 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
269 }
270 for (cnt = 0; cnt < sizeof(fw->stack_ram) / 2 && rval == QLA_SUCCESS;
271 cnt++, risc_address++) {
272 WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address));
273 WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address));
274 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
275
276 for (timer = 6000000; timer; timer--) {
277 /* Check for pending interrupts. */
278 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
279 if (stat & HSR_RISC_INT) {
280 stat &= 0xff;
281
282 if (stat == 0x1 || stat == 0x2) {
283 set_bit(MBX_INTERRUPT,
284 &ha->mbx_cmd_flags);
285
286 mb0 = RD_MAILBOX_REG(ha, reg, 0);
287 mb2 = RD_MAILBOX_REG(ha, reg, 2);
288
289 /* Release mailbox registers. */
290 WRT_REG_WORD(&reg->semaphore, 0);
291 WRT_REG_WORD(&reg->hccr,
292 HCCR_CLR_RISC_INT);
293 RD_REG_WORD(&reg->hccr);
294 break;
295 } else if (stat == 0x10 || stat == 0x11) {
296 set_bit(MBX_INTERRUPT,
297 &ha->mbx_cmd_flags);
298
299 mb0 = RD_MAILBOX_REG(ha, reg, 0);
300 mb2 = RD_MAILBOX_REG(ha, reg, 2);
301
302 WRT_REG_WORD(&reg->hccr,
303 HCCR_CLR_RISC_INT);
304 RD_REG_WORD(&reg->hccr);
305 break;
306 }
307
308 /* clear this intr; it wasn't a mailbox intr */
309 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
310 RD_REG_WORD(&reg->hccr);
311 }
312 udelay(5);
313 }
314
315 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
316 rval = mb0 & MBS_MASK;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700317 fw->stack_ram[cnt] = htons(mb2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 } else {
319 rval = QLA_FUNCTION_FAILED;
320 }
321 }
322
323 if (rval == QLA_SUCCESS) {
324 /* Get data SRAM. */
325 risc_address = 0x11000;
326 data_ram_cnt = ha->fw_memory_size - risc_address + 1;
327 WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED);
328 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
329 }
330 for (cnt = 0; cnt < data_ram_cnt && rval == QLA_SUCCESS;
331 cnt++, risc_address++) {
332 WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address));
333 WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address));
334 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
335
336 for (timer = 6000000; timer; timer--) {
337 /* Check for pending interrupts. */
338 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
339 if (stat & HSR_RISC_INT) {
340 stat &= 0xff;
341
342 if (stat == 0x1 || stat == 0x2) {
343 set_bit(MBX_INTERRUPT,
344 &ha->mbx_cmd_flags);
345
346 mb0 = RD_MAILBOX_REG(ha, reg, 0);
347 mb2 = RD_MAILBOX_REG(ha, reg, 2);
348
349 /* Release mailbox registers. */
350 WRT_REG_WORD(&reg->semaphore, 0);
351 WRT_REG_WORD(&reg->hccr,
352 HCCR_CLR_RISC_INT);
353 RD_REG_WORD(&reg->hccr);
354 break;
355 } else if (stat == 0x10 || stat == 0x11) {
356 set_bit(MBX_INTERRUPT,
357 &ha->mbx_cmd_flags);
358
359 mb0 = RD_MAILBOX_REG(ha, reg, 0);
360 mb2 = RD_MAILBOX_REG(ha, reg, 2);
361
362 WRT_REG_WORD(&reg->hccr,
363 HCCR_CLR_RISC_INT);
364 RD_REG_WORD(&reg->hccr);
365 break;
366 }
367
368 /* clear this intr; it wasn't a mailbox intr */
369 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
370 RD_REG_WORD(&reg->hccr);
371 }
372 udelay(5);
373 }
374
375 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
376 rval = mb0 & MBS_MASK;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700377 fw->data_ram[cnt] = htons(mb2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 } else {
379 rval = QLA_FUNCTION_FAILED;
380 }
381 }
382
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700383 if (rval == QLA_SUCCESS)
384 qla2xxx_copy_queues(ha, &fw->data_ram[cnt]);
385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 if (rval != QLA_SUCCESS) {
387 qla_printk(KERN_WARNING, ha,
388 "Failed to dump firmware (%x)!!!\n", rval);
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700389 ha->fw_dumped = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 } else {
392 qla_printk(KERN_INFO, ha,
393 "Firmware dump saved to temp buffer (%ld/%p).\n",
394 ha->host_no, ha->fw_dump);
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700395 ha->fw_dumped = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 }
397
398qla2300_fw_dump_failed:
399 if (!hardware_locked)
400 spin_unlock_irqrestore(&ha->hardware_lock, flags);
401}
402
403/**
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware.
405 * @ha: HA context
406 * @hardware_locked: Called with the hardware_lock
407 */
408void
409qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
410{
411 int rval;
412 uint32_t cnt, timer;
413 uint16_t risc_address;
414 uint16_t mb0, mb2;
Andrew Vasquez3d716442005-07-06 10:30:26 -0700415 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 uint16_t __iomem *dmp_reg;
417 unsigned long flags;
418 struct qla2100_fw_dump *fw;
419
420 risc_address = 0;
421 mb0 = mb2 = 0;
422 flags = 0;
423
424 if (!hardware_locked)
425 spin_lock_irqsave(&ha->hardware_lock, flags);
426
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700427 if (!ha->fw_dump) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 qla_printk(KERN_WARNING, ha,
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700429 "No buffer available for dump!!!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 goto qla2100_fw_dump_failed;
431 }
432
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700433 if (ha->fw_dumped) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 qla_printk(KERN_WARNING, ha,
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700435 "Firmware has been previously dumped (%p) -- ignoring "
436 "request...\n", ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 goto qla2100_fw_dump_failed;
438 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700439 fw = &ha->fw_dump->isp.isp21;
440 qla2xxx_prep_dump(ha, ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441
442 rval = QLA_SUCCESS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700443 fw->hccr = htons(RD_REG_WORD(&reg->hccr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444
445 /* Pause RISC. */
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700446 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 for (cnt = 30000; (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
448 rval == QLA_SUCCESS; cnt--) {
449 if (cnt)
450 udelay(100);
451 else
452 rval = QLA_FUNCTION_TIMEOUT;
453 }
454 if (rval == QLA_SUCCESS) {
455 dmp_reg = (uint16_t __iomem *)(reg + 0);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700456 for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700457 fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
459 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10);
460 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
461 if (cnt == 8) {
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700462 dmp_reg = (uint16_t __iomem *)
463 ((uint8_t __iomem *)reg + 0xe0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700465 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 }
467
468 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700469 for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700470 fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471
472 WRT_REG_WORD(&reg->ctrl_status, 0x00);
473 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700474 for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700475 fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700477 WRT_REG_WORD(&reg->pcr, 0x2000);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700479 for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700480 fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700482 WRT_REG_WORD(&reg->pcr, 0x2100);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700484 for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700485 fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700487 WRT_REG_WORD(&reg->pcr, 0x2200);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700489 for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700490 fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700492 WRT_REG_WORD(&reg->pcr, 0x2300);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700494 for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700495 fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700497 WRT_REG_WORD(&reg->pcr, 0x2400);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700499 for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700500 fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700502 WRT_REG_WORD(&reg->pcr, 0x2500);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700504 for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700505 fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700507 WRT_REG_WORD(&reg->pcr, 0x2600);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700509 for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700510 fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700512 WRT_REG_WORD(&reg->pcr, 0x2700);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700514 for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700515 fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700517 WRT_REG_WORD(&reg->ctrl_status, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700519 for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700520 fw->frame_buf_hdw_reg[cnt] =
521 htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700523 WRT_REG_WORD(&reg->ctrl_status, 0x20);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700525 for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700526 fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700528 WRT_REG_WORD(&reg->ctrl_status, 0x30);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700530 for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700531 fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
533 /* Reset the ISP. */
534 WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
535 }
536
537 for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
538 rval == QLA_SUCCESS; cnt--) {
539 if (cnt)
540 udelay(100);
541 else
542 rval = QLA_FUNCTION_TIMEOUT;
543 }
544
545 /* Pause RISC. */
546 if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) &&
547 (RD_REG_WORD(&reg->mctr) & (BIT_1 | BIT_0)) != 0))) {
548
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700549 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 for (cnt = 30000;
551 (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
552 rval == QLA_SUCCESS; cnt--) {
553 if (cnt)
554 udelay(100);
555 else
556 rval = QLA_FUNCTION_TIMEOUT;
557 }
558 if (rval == QLA_SUCCESS) {
559 /* Set memory configuration and timing. */
560 if (IS_QLA2100(ha))
561 WRT_REG_WORD(&reg->mctr, 0xf1);
562 else
563 WRT_REG_WORD(&reg->mctr, 0xf2);
564 RD_REG_WORD(&reg->mctr); /* PCI Posting. */
565
566 /* Release RISC. */
567 WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
568 }
569 }
570
571 if (rval == QLA_SUCCESS) {
572 /* Get RISC SRAM. */
573 risc_address = 0x1000;
574 WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
575 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
576 }
577 for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;
578 cnt++, risc_address++) {
579 WRT_MAILBOX_REG(ha, reg, 1, risc_address);
580 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
581
582 for (timer = 6000000; timer != 0; timer--) {
583 /* Check for pending interrupts. */
584 if (RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) {
585 if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
586 set_bit(MBX_INTERRUPT,
587 &ha->mbx_cmd_flags);
588
589 mb0 = RD_MAILBOX_REG(ha, reg, 0);
590 mb2 = RD_MAILBOX_REG(ha, reg, 2);
591
592 WRT_REG_WORD(&reg->semaphore, 0);
593 WRT_REG_WORD(&reg->hccr,
594 HCCR_CLR_RISC_INT);
595 RD_REG_WORD(&reg->hccr);
596 break;
597 }
598 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
599 RD_REG_WORD(&reg->hccr);
600 }
601 udelay(5);
602 }
603
604 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
605 rval = mb0 & MBS_MASK;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700606 fw->risc_ram[cnt] = htons(mb2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 } else {
608 rval = QLA_FUNCTION_FAILED;
609 }
610 }
611
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700612 if (rval == QLA_SUCCESS)
613 qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);
614
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 if (rval != QLA_SUCCESS) {
616 qla_printk(KERN_WARNING, ha,
617 "Failed to dump firmware (%x)!!!\n", rval);
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700618 ha->fw_dumped = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 } else {
621 qla_printk(KERN_INFO, ha,
622 "Firmware dump saved to temp buffer (%ld/%p).\n",
623 ha->host_no, ha->fw_dump);
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700624 ha->fw_dumped = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 }
626
627qla2100_fw_dump_failed:
628 if (!hardware_locked)
629 spin_unlock_irqrestore(&ha->hardware_lock, flags);
630}
631
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700632void
633qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
634{
635 int rval;
636 uint32_t cnt, timer;
637 uint32_t risc_address;
Andrew Vasquez335a1cc2005-11-08 14:37:48 -0800638 uint16_t mb[4], wd;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700639
640 uint32_t stat;
641 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
642 uint32_t __iomem *dmp_reg;
643 uint32_t *iter_reg;
644 uint16_t __iomem *mbx_reg;
645 unsigned long flags;
646 struct qla24xx_fw_dump *fw;
647 uint32_t ext_mem_cnt;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700648 void *eft;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700649
650 risc_address = ext_mem_cnt = 0;
651 memset(mb, 0, sizeof(mb));
652 flags = 0;
653
654 if (!hardware_locked)
655 spin_lock_irqsave(&ha->hardware_lock, flags);
656
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700657 if (!ha->fw_dump) {
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700658 qla_printk(KERN_WARNING, ha,
659 "No buffer available for dump!!!\n");
660 goto qla24xx_fw_dump_failed;
661 }
662
663 if (ha->fw_dumped) {
664 qla_printk(KERN_WARNING, ha,
665 "Firmware has been previously dumped (%p) -- ignoring "
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700666 "request...\n", ha->fw_dump);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700667 goto qla24xx_fw_dump_failed;
668 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700669 fw = &ha->fw_dump->isp.isp24;
670 qla2xxx_prep_dump(ha, ha->fw_dump);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700671
672 rval = QLA_SUCCESS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700673 fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700674
675 /* Pause RISC. */
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800676 if ((RD_REG_DWORD(&reg->hccr) & HCCRX_RISC_PAUSE) == 0) {
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700677 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET |
678 HCCRX_CLR_HOST_INT);
679 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
680 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
681 for (cnt = 30000;
682 (RD_REG_DWORD(&reg->hccr) & HCCRX_RISC_PAUSE) == 0 &&
683 rval == QLA_SUCCESS; cnt--) {
684 if (cnt)
685 udelay(100);
686 else
687 rval = QLA_FUNCTION_TIMEOUT;
688 }
689 }
690
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700691 if (rval == QLA_SUCCESS) {
692 /* Host interface registers. */
693 dmp_reg = (uint32_t __iomem *)(reg + 0);
694 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700695 fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700696
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800697 /* Disable interrupts. */
698 WRT_REG_DWORD(&reg->ictrl, 0);
699 RD_REG_DWORD(&reg->ictrl);
700
701 /* Shadow registers. */
702 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
703 RD_REG_DWORD(&reg->iobase_addr);
704 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
705 WRT_REG_DWORD(dmp_reg, 0xB0000000);
706 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700707 fw->shadow_reg[0] = htonl(RD_REG_DWORD(dmp_reg));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800708
709 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
710 WRT_REG_DWORD(dmp_reg, 0xB0100000);
711 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700712 fw->shadow_reg[1] = htonl(RD_REG_DWORD(dmp_reg));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800713
714 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
715 WRT_REG_DWORD(dmp_reg, 0xB0200000);
716 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700717 fw->shadow_reg[2] = htonl(RD_REG_DWORD(dmp_reg));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800718
719 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
720 WRT_REG_DWORD(dmp_reg, 0xB0300000);
721 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700722 fw->shadow_reg[3] = htonl(RD_REG_DWORD(dmp_reg));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800723
724 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
725 WRT_REG_DWORD(dmp_reg, 0xB0400000);
726 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700727 fw->shadow_reg[4] = htonl(RD_REG_DWORD(dmp_reg));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800728
729 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
730 WRT_REG_DWORD(dmp_reg, 0xB0500000);
731 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700732 fw->shadow_reg[5] = htonl(RD_REG_DWORD(dmp_reg));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800733
734 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
735 WRT_REG_DWORD(dmp_reg, 0xB0600000);
736 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700737 fw->shadow_reg[6] = htonl(RD_REG_DWORD(dmp_reg));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -0800738
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700739 /* Mailbox registers. */
740 mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
741 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700742 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700743
744 /* Transfer sequence registers. */
745 iter_reg = fw->xseq_gp_reg;
746 WRT_REG_DWORD(&reg->iobase_addr, 0xBF00);
747 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
748 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700749 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700750
751 WRT_REG_DWORD(&reg->iobase_addr, 0xBF10);
752 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
753 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700754 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700755
756 WRT_REG_DWORD(&reg->iobase_addr, 0xBF20);
757 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
758 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700759 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700760
761 WRT_REG_DWORD(&reg->iobase_addr, 0xBF30);
762 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
763 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700764 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700765
766 WRT_REG_DWORD(&reg->iobase_addr, 0xBF40);
767 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
768 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700769 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700770
771 WRT_REG_DWORD(&reg->iobase_addr, 0xBF50);
772 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
773 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700774 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700775
776 WRT_REG_DWORD(&reg->iobase_addr, 0xBF60);
777 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
778 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700779 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700780
781 WRT_REG_DWORD(&reg->iobase_addr, 0xBF70);
782 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
783 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700784 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700785
786 WRT_REG_DWORD(&reg->iobase_addr, 0xBFE0);
787 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
788 for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700789 fw->xseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700790
791 WRT_REG_DWORD(&reg->iobase_addr, 0xBFF0);
792 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
793 for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700794 fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700795
796 /* Receive sequence registers. */
797 iter_reg = fw->rseq_gp_reg;
798 WRT_REG_DWORD(&reg->iobase_addr, 0xFF00);
799 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
800 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700801 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700802
803 WRT_REG_DWORD(&reg->iobase_addr, 0xFF10);
804 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
805 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700806 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700807
808 WRT_REG_DWORD(&reg->iobase_addr, 0xFF20);
809 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
810 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700811 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700812
813 WRT_REG_DWORD(&reg->iobase_addr, 0xFF30);
814 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
815 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700816 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700817
818 WRT_REG_DWORD(&reg->iobase_addr, 0xFF40);
819 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
820 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700821 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700822
823 WRT_REG_DWORD(&reg->iobase_addr, 0xFF50);
824 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
825 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700826 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700827
828 WRT_REG_DWORD(&reg->iobase_addr, 0xFF60);
829 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
830 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700831 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700832
833 WRT_REG_DWORD(&reg->iobase_addr, 0xFF70);
834 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
835 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700836 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700837
838 WRT_REG_DWORD(&reg->iobase_addr, 0xFFD0);
839 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
840 for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700841 fw->rseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700842
843 WRT_REG_DWORD(&reg->iobase_addr, 0xFFE0);
844 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
845 for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700846 fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700847
848 WRT_REG_DWORD(&reg->iobase_addr, 0xFFF0);
849 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
850 for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700851 fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700852
853 /* Command DMA registers. */
854 WRT_REG_DWORD(&reg->iobase_addr, 0x7100);
855 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
856 for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700857 fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700858
859 /* Queues. */
860 iter_reg = fw->req0_dma_reg;
861 WRT_REG_DWORD(&reg->iobase_addr, 0x7200);
862 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
863 for (cnt = 0; cnt < 8; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700864 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700865
866 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
867 for (cnt = 0; cnt < 7; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700868 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700869
870 iter_reg = fw->resp0_dma_reg;
871 WRT_REG_DWORD(&reg->iobase_addr, 0x7300);
872 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
873 for (cnt = 0; cnt < 8; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700874 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700875
876 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
877 for (cnt = 0; cnt < 7; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700878 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700879
880 iter_reg = fw->req1_dma_reg;
881 WRT_REG_DWORD(&reg->iobase_addr, 0x7400);
882 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
883 for (cnt = 0; cnt < 8; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700884 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700885
886 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
887 for (cnt = 0; cnt < 7; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700888 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700889
890 /* Transmit DMA registers. */
891 iter_reg = fw->xmt0_dma_reg;
892 WRT_REG_DWORD(&reg->iobase_addr, 0x7600);
893 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
894 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700895 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700896
897 WRT_REG_DWORD(&reg->iobase_addr, 0x7610);
898 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
899 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700900 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700901
902 iter_reg = fw->xmt1_dma_reg;
903 WRT_REG_DWORD(&reg->iobase_addr, 0x7620);
904 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
905 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700906 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700907
908 WRT_REG_DWORD(&reg->iobase_addr, 0x7630);
909 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
910 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700911 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700912
913 iter_reg = fw->xmt2_dma_reg;
914 WRT_REG_DWORD(&reg->iobase_addr, 0x7640);
915 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
916 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700917 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700918
919 WRT_REG_DWORD(&reg->iobase_addr, 0x7650);
920 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
921 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700922 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700923
924 iter_reg = fw->xmt3_dma_reg;
925 WRT_REG_DWORD(&reg->iobase_addr, 0x7660);
926 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
927 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700928 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700929
930 WRT_REG_DWORD(&reg->iobase_addr, 0x7670);
931 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
932 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700933 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700934
935 iter_reg = fw->xmt4_dma_reg;
936 WRT_REG_DWORD(&reg->iobase_addr, 0x7680);
937 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
938 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700939 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700940
941 WRT_REG_DWORD(&reg->iobase_addr, 0x7690);
942 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
943 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700944 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700945
946 WRT_REG_DWORD(&reg->iobase_addr, 0x76A0);
947 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
948 for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700949 fw->xmt_data_dma_reg[cnt] =
950 htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700951
952 /* Receive DMA registers. */
953 iter_reg = fw->rcvt0_data_dma_reg;
954 WRT_REG_DWORD(&reg->iobase_addr, 0x7700);
955 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
956 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700957 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700958
959 WRT_REG_DWORD(&reg->iobase_addr, 0x7710);
960 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
961 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700962 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700963
964 iter_reg = fw->rcvt1_data_dma_reg;
965 WRT_REG_DWORD(&reg->iobase_addr, 0x7720);
966 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
967 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700968 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700969
970 WRT_REG_DWORD(&reg->iobase_addr, 0x7730);
971 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
972 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700973 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700974
975 /* RISC registers. */
976 iter_reg = fw->risc_gp_reg;
977 WRT_REG_DWORD(&reg->iobase_addr, 0x0F00);
978 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
979 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700980 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700981
982 WRT_REG_DWORD(&reg->iobase_addr, 0x0F10);
983 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
984 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700985 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700986
987 WRT_REG_DWORD(&reg->iobase_addr, 0x0F20);
988 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
989 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700990 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700991
992 WRT_REG_DWORD(&reg->iobase_addr, 0x0F30);
993 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
994 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700995 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -0700996
997 WRT_REG_DWORD(&reg->iobase_addr, 0x0F40);
998 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
999 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001000 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001001
1002 WRT_REG_DWORD(&reg->iobase_addr, 0x0F50);
1003 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1004 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001005 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001006
1007 WRT_REG_DWORD(&reg->iobase_addr, 0x0F60);
1008 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1009 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001010 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001011
1012 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1013 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1014 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001015 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001016
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001017 /* Local memory controller registers. */
1018 iter_reg = fw->lmc_reg;
1019 WRT_REG_DWORD(&reg->iobase_addr, 0x3000);
1020 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1021 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001022 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001023
1024 WRT_REG_DWORD(&reg->iobase_addr, 0x3010);
1025 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1026 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001027 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001028
1029 WRT_REG_DWORD(&reg->iobase_addr, 0x3020);
1030 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1031 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001032 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001033
1034 WRT_REG_DWORD(&reg->iobase_addr, 0x3030);
1035 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1036 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001037 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001038
1039 WRT_REG_DWORD(&reg->iobase_addr, 0x3040);
1040 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1041 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001042 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001043
1044 WRT_REG_DWORD(&reg->iobase_addr, 0x3050);
1045 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1046 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001047 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001048
1049 WRT_REG_DWORD(&reg->iobase_addr, 0x3060);
1050 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1051 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001052 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001053
1054 /* Fibre Protocol Module registers. */
1055 iter_reg = fw->fpm_hdw_reg;
1056 WRT_REG_DWORD(&reg->iobase_addr, 0x4000);
1057 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1058 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001059 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001060
1061 WRT_REG_DWORD(&reg->iobase_addr, 0x4010);
1062 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1063 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001064 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001065
1066 WRT_REG_DWORD(&reg->iobase_addr, 0x4020);
1067 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1068 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001069 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001070
1071 WRT_REG_DWORD(&reg->iobase_addr, 0x4030);
1072 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1073 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001074 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001075
1076 WRT_REG_DWORD(&reg->iobase_addr, 0x4040);
1077 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1078 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001079 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001080
1081 WRT_REG_DWORD(&reg->iobase_addr, 0x4050);
1082 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1083 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001084 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001085
1086 WRT_REG_DWORD(&reg->iobase_addr, 0x4060);
1087 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1088 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001089 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001090
1091 WRT_REG_DWORD(&reg->iobase_addr, 0x4070);
1092 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1093 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001094 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001095
1096 WRT_REG_DWORD(&reg->iobase_addr, 0x4080);
1097 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1098 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001099 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001100
1101 WRT_REG_DWORD(&reg->iobase_addr, 0x4090);
1102 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1103 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001104 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001105
1106 WRT_REG_DWORD(&reg->iobase_addr, 0x40A0);
1107 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1108 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001109 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001110
1111 WRT_REG_DWORD(&reg->iobase_addr, 0x40B0);
1112 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1113 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001114 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001115
1116 /* Frame Buffer registers. */
1117 iter_reg = fw->fb_hdw_reg;
1118 WRT_REG_DWORD(&reg->iobase_addr, 0x6000);
1119 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1120 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001121 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001122
1123 WRT_REG_DWORD(&reg->iobase_addr, 0x6010);
1124 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1125 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001126 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001127
1128 WRT_REG_DWORD(&reg->iobase_addr, 0x6020);
1129 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1130 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001131 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001132
1133 WRT_REG_DWORD(&reg->iobase_addr, 0x6030);
1134 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1135 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001136 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001137
1138 WRT_REG_DWORD(&reg->iobase_addr, 0x6040);
1139 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1140 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001141 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001142
1143 WRT_REG_DWORD(&reg->iobase_addr, 0x6100);
1144 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1145 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001146 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001147
1148 WRT_REG_DWORD(&reg->iobase_addr, 0x6130);
1149 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1150 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001151 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001152
1153 WRT_REG_DWORD(&reg->iobase_addr, 0x6150);
1154 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1155 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001156 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001157
1158 WRT_REG_DWORD(&reg->iobase_addr, 0x6170);
1159 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1160 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001161 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001162
1163 WRT_REG_DWORD(&reg->iobase_addr, 0x6190);
1164 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1165 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001166 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001167
1168 WRT_REG_DWORD(&reg->iobase_addr, 0x61B0);
1169 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
1170 for (cnt = 0; cnt < 16; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001171 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001172
1173 /* Reset RISC. */
1174 WRT_REG_DWORD(&reg->ctrl_status,
1175 CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
1176 for (cnt = 0; cnt < 30000; cnt++) {
1177 if ((RD_REG_DWORD(&reg->ctrl_status) &
1178 CSRX_DMA_ACTIVE) == 0)
1179 break;
1180
1181 udelay(10);
1182 }
1183
1184 WRT_REG_DWORD(&reg->ctrl_status,
1185 CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
Andrew Vasquez335a1cc2005-11-08 14:37:48 -08001186 pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
Andrew Vasquez88c26662005-07-08 17:59:26 -07001187
Andrew Vasquez335a1cc2005-11-08 14:37:48 -08001188 udelay(100);
Andrew Vasquez88c26662005-07-08 17:59:26 -07001189 /* Wait for firmware to complete NVRAM accesses. */
Andrew Vasquez88c26662005-07-08 17:59:26 -07001190 mb[0] = (uint32_t) RD_REG_WORD(&reg->mailbox0);
1191 for (cnt = 10000 ; cnt && mb[0]; cnt--) {
1192 udelay(5);
1193 mb[0] = (uint32_t) RD_REG_WORD(&reg->mailbox0);
1194 barrier();
1195 }
1196
Andrew Vasquez335a1cc2005-11-08 14:37:48 -08001197 /* Wait for soft-reset to complete. */
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001198 for (cnt = 0; cnt < 30000; cnt++) {
1199 if ((RD_REG_DWORD(&reg->ctrl_status) &
1200 CSRX_ISP_SOFT_RESET) == 0)
1201 break;
1202
1203 udelay(10);
1204 }
1205 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
1206 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
1207 }
1208
1209 for (cnt = 30000; RD_REG_WORD(&reg->mailbox0) != 0 &&
1210 rval == QLA_SUCCESS; cnt--) {
1211 if (cnt)
1212 udelay(100);
1213 else
1214 rval = QLA_FUNCTION_TIMEOUT;
1215 }
1216
1217 /* Memory. */
1218 if (rval == QLA_SUCCESS) {
1219 /* Code RAM. */
1220 risc_address = 0x20000;
1221 WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);
1222 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1223 }
1224 for (cnt = 0; cnt < sizeof(fw->code_ram) / 4 && rval == QLA_SUCCESS;
1225 cnt++, risc_address++) {
1226 WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));
1227 WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));
1228 RD_REG_WORD(&reg->mailbox8);
1229 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
1230
1231 for (timer = 6000000; timer; timer--) {
1232 /* Check for pending interrupts. */
1233 stat = RD_REG_DWORD(&reg->host_status);
1234 if (stat & HSRX_RISC_INT) {
1235 stat &= 0xff;
1236
1237 if (stat == 0x1 || stat == 0x2 ||
1238 stat == 0x10 || stat == 0x11) {
1239 set_bit(MBX_INTERRUPT,
1240 &ha->mbx_cmd_flags);
1241
1242 mb[0] = RD_REG_WORD(&reg->mailbox0);
1243 mb[2] = RD_REG_WORD(&reg->mailbox2);
1244 mb[3] = RD_REG_WORD(&reg->mailbox3);
1245
1246 WRT_REG_DWORD(&reg->hccr,
1247 HCCRX_CLR_RISC_INT);
1248 RD_REG_DWORD(&reg->hccr);
1249 break;
1250 }
1251
1252 /* Clear this intr; it wasn't a mailbox intr */
1253 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1254 RD_REG_DWORD(&reg->hccr);
1255 }
1256 udelay(5);
1257 }
1258
1259 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
1260 rval = mb[0] & MBS_MASK;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001261 fw->code_ram[cnt] = htonl((mb[3] << 16) | mb[2]);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001262 } else {
1263 rval = QLA_FUNCTION_FAILED;
1264 }
1265 }
1266
1267 if (rval == QLA_SUCCESS) {
1268 /* External Memory. */
1269 risc_address = 0x100000;
1270 ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1;
1271 WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);
1272 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1273 }
1274 for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS;
1275 cnt++, risc_address++) {
1276 WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));
1277 WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));
1278 RD_REG_WORD(&reg->mailbox8);
1279 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
1280
1281 for (timer = 6000000; timer; timer--) {
1282 /* Check for pending interrupts. */
1283 stat = RD_REG_DWORD(&reg->host_status);
1284 if (stat & HSRX_RISC_INT) {
1285 stat &= 0xff;
1286
1287 if (stat == 0x1 || stat == 0x2 ||
1288 stat == 0x10 || stat == 0x11) {
1289 set_bit(MBX_INTERRUPT,
1290 &ha->mbx_cmd_flags);
1291
1292 mb[0] = RD_REG_WORD(&reg->mailbox0);
1293 mb[2] = RD_REG_WORD(&reg->mailbox2);
1294 mb[3] = RD_REG_WORD(&reg->mailbox3);
1295
1296 WRT_REG_DWORD(&reg->hccr,
1297 HCCRX_CLR_RISC_INT);
1298 RD_REG_DWORD(&reg->hccr);
1299 break;
1300 }
1301
1302 /* Clear this intr; it wasn't a mailbox intr */
1303 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1304 RD_REG_DWORD(&reg->hccr);
1305 }
1306 udelay(5);
1307 }
1308
1309 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
1310 rval = mb[0] & MBS_MASK;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001311 fw->ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001312 } else {
1313 rval = QLA_FUNCTION_FAILED;
1314 }
1315 }
1316
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001317 if (rval == QLA_SUCCESS) {
1318 eft = qla2xxx_copy_queues(ha, &fw->ext_mem[cnt]);
1319 if (ha->eft)
1320 memcpy(eft, ha->eft, ntohl(ha->fw_dump->eft_size));
1321 }
1322
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001323 if (rval != QLA_SUCCESS) {
1324 qla_printk(KERN_WARNING, ha,
1325 "Failed to dump firmware (%x)!!!\n", rval);
1326 ha->fw_dumped = 0;
1327
1328 } else {
1329 qla_printk(KERN_INFO, ha,
1330 "Firmware dump saved to temp buffer (%ld/%p).\n",
Andrew Vasquezd4e3e042006-05-17 15:09:50 -07001331 ha->host_no, ha->fw_dump);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001332 ha->fw_dumped = 1;
1333 }
1334
1335qla24xx_fw_dump_failed:
1336 if (!hardware_locked)
1337 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1338}
1339
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340/****************************************************************************/
1341/* Driver Debug Functions. */
1342/****************************************************************************/
1343
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001344void
1345qla2x00_dump_regs(scsi_qla_host_t *ha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346{
Andrew Vasquez3d716442005-07-06 10:30:26 -07001347 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348
1349 printk("Mailbox registers:\n");
1350 printk("scsi(%ld): mbox 0 0x%04x \n",
1351 ha->host_no, RD_MAILBOX_REG(ha, reg, 0));
1352 printk("scsi(%ld): mbox 1 0x%04x \n",
1353 ha->host_no, RD_MAILBOX_REG(ha, reg, 1));
1354 printk("scsi(%ld): mbox 2 0x%04x \n",
1355 ha->host_no, RD_MAILBOX_REG(ha, reg, 2));
1356 printk("scsi(%ld): mbox 3 0x%04x \n",
1357 ha->host_no, RD_MAILBOX_REG(ha, reg, 3));
1358 printk("scsi(%ld): mbox 4 0x%04x \n",
1359 ha->host_no, RD_MAILBOX_REG(ha, reg, 4));
1360 printk("scsi(%ld): mbox 5 0x%04x \n",
1361 ha->host_no, RD_MAILBOX_REG(ha, reg, 5));
1362}
1363
1364
1365void
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001366qla2x00_dump_buffer(uint8_t * b, uint32_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367{
1368 uint32_t cnt;
1369 uint8_t c;
1370
1371 printk(" 0 1 2 3 4 5 6 7 8 9 "
1372 "Ah Bh Ch Dh Eh Fh\n");
1373 printk("----------------------------------------"
1374 "----------------------\n");
1375
1376 for (cnt = 0; cnt < size;) {
1377 c = *b++;
1378 printk("%02x",(uint32_t) c);
1379 cnt++;
1380 if (!(cnt % 16))
1381 printk("\n");
1382 else
1383 printk(" ");
1384 }
1385 if (cnt % 16)
1386 printk("\n");
1387}
1388
1389/**************************************************************************
1390 * qla2x00_print_scsi_cmd
1391 * Dumps out info about the scsi cmd and srb.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001392 * Input
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 * cmd : struct scsi_cmnd
1394 **************************************************************************/
1395void
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001396qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397{
1398 int i;
1399 struct scsi_qla_host *ha;
1400 srb_t *sp;
1401
1402 ha = (struct scsi_qla_host *)cmd->device->host->hostdata;
1403
1404 sp = (srb_t *) cmd->SCp.ptr;
1405 printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble);
1406 printk(" chan=0x%02x, target=0x%02x, lun=0x%02x, cmd_len=0x%02x\n",
1407 cmd->device->channel, cmd->device->id, cmd->device->lun,
1408 cmd->cmd_len);
1409 printk(" CDB: ");
1410 for (i = 0; i < cmd->cmd_len; i++) {
1411 printk("0x%02x ", cmd->cmnd[i]);
1412 }
c6295cd2005-04-03 14:59:11 -05001413 printk("\n seg_cnt=%d, allowed=%d, retries=%d\n",
1414 cmd->use_sg, cmd->allowed, cmd->retries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 printk(" request buffer=0x%p, request buffer len=0x%x\n",
1416 cmd->request_buffer, cmd->request_bufflen);
1417 printk(" tag=%d, transfersize=0x%x\n",
1418 cmd->tag, cmd->transfersize);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001419 printk(" serial_number=%lx, SP=%p\n", cmd->serial_number, sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 printk(" data direction=%d\n", cmd->sc_data_direction);
1421
1422 if (!sp)
1423 return;
1424
1425 printk(" sp flags=0x%x\n", sp->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426}
1427
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001428void
1429qla2x00_dump_pkt(void *pkt)
1430{
1431 uint32_t i;
1432 uint8_t *data = (uint8_t *) pkt;
1433
1434 for (i = 0; i < 64; i++) {
1435 if (!(i % 4))
1436 printk("\n%02x: ", i);
1437
1438 printk("%02x ", data[i]);
1439 }
1440 printk("\n");
1441}
1442
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443#if defined(QL_DEBUG_ROUTINES)
1444/*
1445 * qla2x00_formatted_dump_buffer
1446 * Prints string plus buffer.
1447 *
1448 * Input:
1449 * string = Null terminated string (no newline at end).
1450 * buffer = buffer address.
1451 * wd_size = word size 8, 16, 32 or 64 bits
1452 * count = number of words.
1453 */
1454void
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001455qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer,
1456 uint8_t wd_size, uint32_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457{
1458 uint32_t cnt;
1459 uint16_t *buf16;
1460 uint32_t *buf32;
1461
1462 if (strcmp(string, "") != 0)
1463 printk("%s\n",string);
1464
1465 switch (wd_size) {
1466 case 8:
1467 printk(" 0 1 2 3 4 5 6 7 "
1468 "8 9 Ah Bh Ch Dh Eh Fh\n");
1469 printk("-----------------------------------------"
1470 "-------------------------------------\n");
1471
1472 for (cnt = 1; cnt <= count; cnt++, buffer++) {
1473 printk("%02x",*buffer);
1474 if (cnt % 16 == 0)
1475 printk("\n");
1476 else
1477 printk(" ");
1478 }
1479 if (cnt % 16 != 0)
1480 printk("\n");
1481 break;
1482 case 16:
1483 printk(" 0 2 4 6 8 Ah "
1484 " Ch Eh\n");
1485 printk("-----------------------------------------"
1486 "-------------\n");
1487
1488 buf16 = (uint16_t *) buffer;
1489 for (cnt = 1; cnt <= count; cnt++, buf16++) {
1490 printk("%4x",*buf16);
1491
1492 if (cnt % 8 == 0)
1493 printk("\n");
1494 else if (*buf16 < 10)
1495 printk(" ");
1496 else
1497 printk(" ");
1498 }
1499 if (cnt % 8 != 0)
1500 printk("\n");
1501 break;
1502 case 32:
1503 printk(" 0 4 8 Ch\n");
1504 printk("------------------------------------------\n");
1505
1506 buf32 = (uint32_t *) buffer;
1507 for (cnt = 1; cnt <= count; cnt++, buf32++) {
1508 printk("%8x", *buf32);
1509
1510 if (cnt % 4 == 0)
1511 printk("\n");
1512 else if (*buf32 < 10)
1513 printk(" ");
1514 else
1515 printk(" ");
1516 }
1517 if (cnt % 4 != 0)
1518 printk("\n");
1519 break;
1520 default:
1521 break;
1522 }
1523}
1524#endif