diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_dbg.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 1158 |
1 files changed, 1158 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c new file mode 100644 index 000000000000..dcc33daa5913 --- /dev/null +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -0,0 +1,1158 @@ | |||
1 | /* | ||
2 | * QLOGIC LINUX SOFTWARE | ||
3 | * | ||
4 | * QLogic ISP2x00 device driver for Linux 2.6.x | ||
5 | * Copyright (C) 2003-2004 QLogic Corporation | ||
6 | * (www.qlogic.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2, or (at your option) any | ||
11 | * later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | #include "qla_def.h" | ||
20 | |||
21 | #include <linux/delay.h> | ||
22 | |||
23 | static int qla_uprintf(char **, char *, ...); | ||
24 | |||
25 | /** | ||
26 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. | ||
27 | * @ha: HA context | ||
28 | * @hardware_locked: Called with the hardware_lock | ||
29 | */ | ||
30 | void | ||
31 | qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | ||
32 | { | ||
33 | int rval; | ||
34 | uint32_t cnt, timer; | ||
35 | uint32_t risc_address; | ||
36 | uint16_t mb0, mb2; | ||
37 | |||
38 | uint32_t stat; | ||
39 | device_reg_t __iomem *reg = ha->iobase; | ||
40 | uint16_t __iomem *dmp_reg; | ||
41 | unsigned long flags; | ||
42 | struct qla2300_fw_dump *fw; | ||
43 | uint32_t dump_size, data_ram_cnt; | ||
44 | |||
45 | risc_address = data_ram_cnt = 0; | ||
46 | mb0 = mb2 = 0; | ||
47 | flags = 0; | ||
48 | |||
49 | if (!hardware_locked) | ||
50 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
51 | |||
52 | if (ha->fw_dump != NULL) { | ||
53 | qla_printk(KERN_WARNING, ha, | ||
54 | "Firmware has been previously dumped (%p) -- ignoring " | ||
55 | "request...\n", ha->fw_dump); | ||
56 | goto qla2300_fw_dump_failed; | ||
57 | } | ||
58 | |||
59 | /* Allocate (large) dump buffer. */ | ||
60 | dump_size = sizeof(struct qla2300_fw_dump); | ||
61 | dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t); | ||
62 | ha->fw_dump_order = get_order(dump_size); | ||
63 | ha->fw_dump = (struct qla2300_fw_dump *) __get_free_pages(GFP_ATOMIC, | ||
64 | ha->fw_dump_order); | ||
65 | if (ha->fw_dump == NULL) { | ||
66 | qla_printk(KERN_WARNING, ha, | ||
67 | "Unable to allocated memory for firmware dump (%d/%d).\n", | ||
68 | ha->fw_dump_order, dump_size); | ||
69 | goto qla2300_fw_dump_failed; | ||
70 | } | ||
71 | fw = ha->fw_dump; | ||
72 | |||
73 | rval = QLA_SUCCESS; | ||
74 | fw->hccr = RD_REG_WORD(®->hccr); | ||
75 | |||
76 | /* Pause RISC. */ | ||
77 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); | ||
78 | if (IS_QLA2300(ha)) { | ||
79 | for (cnt = 30000; | ||
80 | (RD_REG_WORD(®->hccr) & HCCR_RISC_PAUSE) == 0 && | ||
81 | rval == QLA_SUCCESS; cnt--) { | ||
82 | if (cnt) | ||
83 | udelay(100); | ||
84 | else | ||
85 | rval = QLA_FUNCTION_TIMEOUT; | ||
86 | } | ||
87 | } else { | ||
88 | RD_REG_WORD(®->hccr); /* PCI Posting. */ | ||
89 | udelay(10); | ||
90 | } | ||
91 | |||
92 | if (rval == QLA_SUCCESS) { | ||
93 | dmp_reg = (uint16_t __iomem *)(reg + 0); | ||
94 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) | ||
95 | fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
96 | |||
97 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); | ||
98 | for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) | ||
99 | fw->risc_host_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
100 | |||
101 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40); | ||
102 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | ||
103 | fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
104 | |||
105 | WRT_REG_WORD(®->ctrl_status, 0x40); | ||
106 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
107 | for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++) | ||
108 | fw->resp_dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
109 | |||
110 | WRT_REG_WORD(®->ctrl_status, 0x50); | ||
111 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
112 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) | ||
113 | fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
114 | |||
115 | WRT_REG_WORD(®->ctrl_status, 0x00); | ||
116 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); | ||
117 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) | ||
118 | fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
119 | |||
120 | WRT_REG_WORD(®->pcr, 0x2000); | ||
121 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
122 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) | ||
123 | fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
124 | |||
125 | WRT_REG_WORD(®->pcr, 0x2200); | ||
126 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
127 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) | ||
128 | fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
129 | |||
130 | WRT_REG_WORD(®->pcr, 0x2400); | ||
131 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
132 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) | ||
133 | fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
134 | |||
135 | WRT_REG_WORD(®->pcr, 0x2600); | ||
136 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
137 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) | ||
138 | fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
139 | |||
140 | WRT_REG_WORD(®->pcr, 0x2800); | ||
141 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
142 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) | ||
143 | fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
144 | |||
145 | WRT_REG_WORD(®->pcr, 0x2A00); | ||
146 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
147 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) | ||
148 | fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
149 | |||
150 | WRT_REG_WORD(®->pcr, 0x2C00); | ||
151 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
152 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) | ||
153 | fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
154 | |||
155 | WRT_REG_WORD(®->pcr, 0x2E00); | ||
156 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
157 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) | ||
158 | fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
159 | |||
160 | WRT_REG_WORD(®->ctrl_status, 0x10); | ||
161 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
162 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) | ||
163 | fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
164 | |||
165 | WRT_REG_WORD(®->ctrl_status, 0x20); | ||
166 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
167 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) | ||
168 | fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
169 | |||
170 | WRT_REG_WORD(®->ctrl_status, 0x30); | ||
171 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
172 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) | ||
173 | fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
174 | |||
175 | /* Reset RISC. */ | ||
176 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | ||
177 | for (cnt = 0; cnt < 30000; cnt++) { | ||
178 | if ((RD_REG_WORD(®->ctrl_status) & | ||
179 | CSR_ISP_SOFT_RESET) == 0) | ||
180 | break; | ||
181 | |||
182 | udelay(10); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | if (!IS_QLA2300(ha)) { | ||
187 | for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 && | ||
188 | rval == QLA_SUCCESS; cnt--) { | ||
189 | if (cnt) | ||
190 | udelay(100); | ||
191 | else | ||
192 | rval = QLA_FUNCTION_TIMEOUT; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | if (rval == QLA_SUCCESS) { | ||
197 | /* Get RISC SRAM. */ | ||
198 | risc_address = 0x800; | ||
199 | WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD); | ||
200 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
201 | } | ||
202 | for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS; | ||
203 | cnt++, risc_address++) { | ||
204 | WRT_MAILBOX_REG(ha, reg, 1, (uint16_t)risc_address); | ||
205 | WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT); | ||
206 | |||
207 | for (timer = 6000000; timer; timer--) { | ||
208 | /* Check for pending interrupts. */ | ||
209 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | ||
210 | if (stat & HSR_RISC_INT) { | ||
211 | stat &= 0xff; | ||
212 | |||
213 | if (stat == 0x1 || stat == 0x2) { | ||
214 | set_bit(MBX_INTERRUPT, | ||
215 | &ha->mbx_cmd_flags); | ||
216 | |||
217 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
218 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
219 | |||
220 | /* Release mailbox registers. */ | ||
221 | WRT_REG_WORD(®->semaphore, 0); | ||
222 | WRT_REG_WORD(®->hccr, | ||
223 | HCCR_CLR_RISC_INT); | ||
224 | RD_REG_WORD(®->hccr); | ||
225 | break; | ||
226 | } else if (stat == 0x10 || stat == 0x11) { | ||
227 | set_bit(MBX_INTERRUPT, | ||
228 | &ha->mbx_cmd_flags); | ||
229 | |||
230 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
231 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
232 | |||
233 | WRT_REG_WORD(®->hccr, | ||
234 | HCCR_CLR_RISC_INT); | ||
235 | RD_REG_WORD(®->hccr); | ||
236 | break; | ||
237 | } | ||
238 | |||
239 | /* clear this intr; it wasn't a mailbox intr */ | ||
240 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | ||
241 | RD_REG_WORD(®->hccr); | ||
242 | } | ||
243 | udelay(5); | ||
244 | } | ||
245 | |||
246 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
247 | rval = mb0 & MBS_MASK; | ||
248 | fw->risc_ram[cnt] = mb2; | ||
249 | } else { | ||
250 | rval = QLA_FUNCTION_FAILED; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | if (rval == QLA_SUCCESS) { | ||
255 | /* Get stack SRAM. */ | ||
256 | risc_address = 0x10000; | ||
257 | WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED); | ||
258 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
259 | } | ||
260 | for (cnt = 0; cnt < sizeof(fw->stack_ram) / 2 && rval == QLA_SUCCESS; | ||
261 | cnt++, risc_address++) { | ||
262 | WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address)); | ||
263 | WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address)); | ||
264 | WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT); | ||
265 | |||
266 | for (timer = 6000000; timer; timer--) { | ||
267 | /* Check for pending interrupts. */ | ||
268 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | ||
269 | if (stat & HSR_RISC_INT) { | ||
270 | stat &= 0xff; | ||
271 | |||
272 | if (stat == 0x1 || stat == 0x2) { | ||
273 | set_bit(MBX_INTERRUPT, | ||
274 | &ha->mbx_cmd_flags); | ||
275 | |||
276 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
277 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
278 | |||
279 | /* Release mailbox registers. */ | ||
280 | WRT_REG_WORD(®->semaphore, 0); | ||
281 | WRT_REG_WORD(®->hccr, | ||
282 | HCCR_CLR_RISC_INT); | ||
283 | RD_REG_WORD(®->hccr); | ||
284 | break; | ||
285 | } else if (stat == 0x10 || stat == 0x11) { | ||
286 | set_bit(MBX_INTERRUPT, | ||
287 | &ha->mbx_cmd_flags); | ||
288 | |||
289 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
290 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
291 | |||
292 | WRT_REG_WORD(®->hccr, | ||
293 | HCCR_CLR_RISC_INT); | ||
294 | RD_REG_WORD(®->hccr); | ||
295 | break; | ||
296 | } | ||
297 | |||
298 | /* clear this intr; it wasn't a mailbox intr */ | ||
299 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | ||
300 | RD_REG_WORD(®->hccr); | ||
301 | } | ||
302 | udelay(5); | ||
303 | } | ||
304 | |||
305 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
306 | rval = mb0 & MBS_MASK; | ||
307 | fw->stack_ram[cnt] = mb2; | ||
308 | } else { | ||
309 | rval = QLA_FUNCTION_FAILED; | ||
310 | } | ||
311 | } | ||
312 | |||
313 | if (rval == QLA_SUCCESS) { | ||
314 | /* Get data SRAM. */ | ||
315 | risc_address = 0x11000; | ||
316 | data_ram_cnt = ha->fw_memory_size - risc_address + 1; | ||
317 | WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED); | ||
318 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
319 | } | ||
320 | for (cnt = 0; cnt < data_ram_cnt && rval == QLA_SUCCESS; | ||
321 | cnt++, risc_address++) { | ||
322 | WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address)); | ||
323 | WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address)); | ||
324 | WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT); | ||
325 | |||
326 | for (timer = 6000000; timer; timer--) { | ||
327 | /* Check for pending interrupts. */ | ||
328 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | ||
329 | if (stat & HSR_RISC_INT) { | ||
330 | stat &= 0xff; | ||
331 | |||
332 | if (stat == 0x1 || stat == 0x2) { | ||
333 | set_bit(MBX_INTERRUPT, | ||
334 | &ha->mbx_cmd_flags); | ||
335 | |||
336 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
337 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
338 | |||
339 | /* Release mailbox registers. */ | ||
340 | WRT_REG_WORD(®->semaphore, 0); | ||
341 | WRT_REG_WORD(®->hccr, | ||
342 | HCCR_CLR_RISC_INT); | ||
343 | RD_REG_WORD(®->hccr); | ||
344 | break; | ||
345 | } else if (stat == 0x10 || stat == 0x11) { | ||
346 | set_bit(MBX_INTERRUPT, | ||
347 | &ha->mbx_cmd_flags); | ||
348 | |||
349 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
350 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
351 | |||
352 | WRT_REG_WORD(®->hccr, | ||
353 | HCCR_CLR_RISC_INT); | ||
354 | RD_REG_WORD(®->hccr); | ||
355 | break; | ||
356 | } | ||
357 | |||
358 | /* clear this intr; it wasn't a mailbox intr */ | ||
359 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | ||
360 | RD_REG_WORD(®->hccr); | ||
361 | } | ||
362 | udelay(5); | ||
363 | } | ||
364 | |||
365 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
366 | rval = mb0 & MBS_MASK; | ||
367 | fw->data_ram[cnt] = mb2; | ||
368 | } else { | ||
369 | rval = QLA_FUNCTION_FAILED; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | |||
374 | if (rval != QLA_SUCCESS) { | ||
375 | qla_printk(KERN_WARNING, ha, | ||
376 | "Failed to dump firmware (%x)!!!\n", rval); | ||
377 | |||
378 | free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order); | ||
379 | ha->fw_dump = NULL; | ||
380 | } else { | ||
381 | qla_printk(KERN_INFO, ha, | ||
382 | "Firmware dump saved to temp buffer (%ld/%p).\n", | ||
383 | ha->host_no, ha->fw_dump); | ||
384 | } | ||
385 | |||
386 | qla2300_fw_dump_failed: | ||
387 | if (!hardware_locked) | ||
388 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * qla2300_ascii_fw_dump() - Converts a binary firmware dump to ASCII. | ||
393 | * @ha: HA context | ||
394 | */ | ||
395 | void | ||
396 | qla2300_ascii_fw_dump(scsi_qla_host_t *ha) | ||
397 | { | ||
398 | uint32_t cnt; | ||
399 | char *uiter; | ||
400 | char fw_info[30]; | ||
401 | struct qla2300_fw_dump *fw; | ||
402 | uint32_t data_ram_cnt; | ||
403 | |||
404 | uiter = ha->fw_dump_buffer; | ||
405 | fw = ha->fw_dump; | ||
406 | |||
407 | qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number, | ||
408 | qla2x00_get_fw_version_str(ha, fw_info)); | ||
409 | |||
410 | qla_uprintf(&uiter, "\n[==>BEG]\n"); | ||
411 | |||
412 | qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr); | ||
413 | |||
414 | qla_uprintf(&uiter, "PBIU Registers:"); | ||
415 | for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) { | ||
416 | if (cnt % 8 == 0) { | ||
417 | qla_uprintf(&uiter, "\n"); | ||
418 | } | ||
419 | qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]); | ||
420 | } | ||
421 | |||
422 | qla_uprintf(&uiter, "\n\nReqQ-RspQ-Risc2Host Status registers:"); | ||
423 | for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) { | ||
424 | if (cnt % 8 == 0) { | ||
425 | qla_uprintf(&uiter, "\n"); | ||
426 | } | ||
427 | qla_uprintf(&uiter, "%04x ", fw->risc_host_reg[cnt]); | ||
428 | } | ||
429 | |||
430 | qla_uprintf(&uiter, "\n\nMailbox Registers:"); | ||
431 | for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) { | ||
432 | if (cnt % 8 == 0) { | ||
433 | qla_uprintf(&uiter, "\n"); | ||
434 | } | ||
435 | qla_uprintf(&uiter, "%04x ", fw->mailbox_reg[cnt]); | ||
436 | } | ||
437 | |||
438 | qla_uprintf(&uiter, "\n\nAuto Request Response DMA Registers:"); | ||
439 | for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) { | ||
440 | if (cnt % 8 == 0) { | ||
441 | qla_uprintf(&uiter, "\n"); | ||
442 | } | ||
443 | qla_uprintf(&uiter, "%04x ", fw->resp_dma_reg[cnt]); | ||
444 | } | ||
445 | |||
446 | qla_uprintf(&uiter, "\n\nDMA Registers:"); | ||
447 | for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) { | ||
448 | if (cnt % 8 == 0) { | ||
449 | qla_uprintf(&uiter, "\n"); | ||
450 | } | ||
451 | qla_uprintf(&uiter, "%04x ", fw->dma_reg[cnt]); | ||
452 | } | ||
453 | |||
454 | qla_uprintf(&uiter, "\n\nRISC Hardware Registers:"); | ||
455 | for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) { | ||
456 | if (cnt % 8 == 0) { | ||
457 | qla_uprintf(&uiter, "\n"); | ||
458 | } | ||
459 | qla_uprintf(&uiter, "%04x ", fw->risc_hdw_reg[cnt]); | ||
460 | } | ||
461 | |||
462 | qla_uprintf(&uiter, "\n\nRISC GP0 Registers:"); | ||
463 | for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) { | ||
464 | if (cnt % 8 == 0) { | ||
465 | qla_uprintf(&uiter, "\n"); | ||
466 | } | ||
467 | qla_uprintf(&uiter, "%04x ", fw->risc_gp0_reg[cnt]); | ||
468 | } | ||
469 | |||
470 | qla_uprintf(&uiter, "\n\nRISC GP1 Registers:"); | ||
471 | for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) { | ||
472 | if (cnt % 8 == 0) { | ||
473 | qla_uprintf(&uiter, "\n"); | ||
474 | } | ||
475 | qla_uprintf(&uiter, "%04x ", fw->risc_gp1_reg[cnt]); | ||
476 | } | ||
477 | |||
478 | qla_uprintf(&uiter, "\n\nRISC GP2 Registers:"); | ||
479 | for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) { | ||
480 | if (cnt % 8 == 0) { | ||
481 | qla_uprintf(&uiter, "\n"); | ||
482 | } | ||
483 | qla_uprintf(&uiter, "%04x ", fw->risc_gp2_reg[cnt]); | ||
484 | } | ||
485 | |||
486 | qla_uprintf(&uiter, "\n\nRISC GP3 Registers:"); | ||
487 | for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) { | ||
488 | if (cnt % 8 == 0) { | ||
489 | qla_uprintf(&uiter, "\n"); | ||
490 | } | ||
491 | qla_uprintf(&uiter, "%04x ", fw->risc_gp3_reg[cnt]); | ||
492 | } | ||
493 | |||
494 | qla_uprintf(&uiter, "\n\nRISC GP4 Registers:"); | ||
495 | for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) { | ||
496 | if (cnt % 8 == 0) { | ||
497 | qla_uprintf(&uiter, "\n"); | ||
498 | } | ||
499 | qla_uprintf(&uiter, "%04x ", fw->risc_gp4_reg[cnt]); | ||
500 | } | ||
501 | |||
502 | qla_uprintf(&uiter, "\n\nRISC GP5 Registers:"); | ||
503 | for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) { | ||
504 | if (cnt % 8 == 0) { | ||
505 | qla_uprintf(&uiter, "\n"); | ||
506 | } | ||
507 | qla_uprintf(&uiter, "%04x ", fw->risc_gp5_reg[cnt]); | ||
508 | } | ||
509 | |||
510 | qla_uprintf(&uiter, "\n\nRISC GP6 Registers:"); | ||
511 | for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) { | ||
512 | if (cnt % 8 == 0) { | ||
513 | qla_uprintf(&uiter, "\n"); | ||
514 | } | ||
515 | qla_uprintf(&uiter, "%04x ", fw->risc_gp6_reg[cnt]); | ||
516 | } | ||
517 | |||
518 | qla_uprintf(&uiter, "\n\nRISC GP7 Registers:"); | ||
519 | for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) { | ||
520 | if (cnt % 8 == 0) { | ||
521 | qla_uprintf(&uiter, "\n"); | ||
522 | } | ||
523 | qla_uprintf(&uiter, "%04x ", fw->risc_gp7_reg[cnt]); | ||
524 | } | ||
525 | |||
526 | qla_uprintf(&uiter, "\n\nFrame Buffer Hardware Registers:"); | ||
527 | for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) { | ||
528 | if (cnt % 8 == 0) { | ||
529 | qla_uprintf(&uiter, "\n"); | ||
530 | } | ||
531 | qla_uprintf(&uiter, "%04x ", fw->frame_buf_hdw_reg[cnt]); | ||
532 | } | ||
533 | |||
534 | qla_uprintf(&uiter, "\n\nFPM B0 Registers:"); | ||
535 | for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) { | ||
536 | if (cnt % 8 == 0) { | ||
537 | qla_uprintf(&uiter, "\n"); | ||
538 | } | ||
539 | qla_uprintf(&uiter, "%04x ", fw->fpm_b0_reg[cnt]); | ||
540 | } | ||
541 | |||
542 | qla_uprintf(&uiter, "\n\nFPM B1 Registers:"); | ||
543 | for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) { | ||
544 | if (cnt % 8 == 0) { | ||
545 | qla_uprintf(&uiter, "\n"); | ||
546 | } | ||
547 | qla_uprintf(&uiter, "%04x ", fw->fpm_b1_reg[cnt]); | ||
548 | } | ||
549 | |||
550 | qla_uprintf(&uiter, "\n\nCode RAM Dump:"); | ||
551 | for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) { | ||
552 | if (cnt % 8 == 0) { | ||
553 | qla_uprintf(&uiter, "\n%04x: ", cnt + 0x0800); | ||
554 | } | ||
555 | qla_uprintf(&uiter, "%04x ", fw->risc_ram[cnt]); | ||
556 | } | ||
557 | |||
558 | qla_uprintf(&uiter, "\n\nStack RAM Dump:"); | ||
559 | for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) { | ||
560 | if (cnt % 8 == 0) { | ||
561 | qla_uprintf(&uiter, "\n%05x: ", cnt + 0x10000); | ||
562 | } | ||
563 | qla_uprintf(&uiter, "%04x ", fw->stack_ram[cnt]); | ||
564 | } | ||
565 | |||
566 | qla_uprintf(&uiter, "\n\nData RAM Dump:"); | ||
567 | data_ram_cnt = ha->fw_memory_size - 0x11000 + 1; | ||
568 | for (cnt = 0; cnt < data_ram_cnt; cnt++) { | ||
569 | if (cnt % 8 == 0) { | ||
570 | qla_uprintf(&uiter, "\n%05x: ", cnt + 0x11000); | ||
571 | } | ||
572 | qla_uprintf(&uiter, "%04x ", fw->data_ram[cnt]); | ||
573 | } | ||
574 | |||
575 | qla_uprintf(&uiter, "\n\n[<==END] ISP Debug Dump."); | ||
576 | } | ||
577 | |||
578 | /** | ||
579 | * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. | ||
580 | * @ha: HA context | ||
581 | * @hardware_locked: Called with the hardware_lock | ||
582 | */ | ||
583 | void | ||
584 | qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | ||
585 | { | ||
586 | int rval; | ||
587 | uint32_t cnt, timer; | ||
588 | uint16_t risc_address; | ||
589 | uint16_t mb0, mb2; | ||
590 | device_reg_t __iomem *reg = ha->iobase; | ||
591 | uint16_t __iomem *dmp_reg; | ||
592 | unsigned long flags; | ||
593 | struct qla2100_fw_dump *fw; | ||
594 | |||
595 | risc_address = 0; | ||
596 | mb0 = mb2 = 0; | ||
597 | flags = 0; | ||
598 | |||
599 | if (!hardware_locked) | ||
600 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
601 | |||
602 | if (ha->fw_dump != NULL) { | ||
603 | qla_printk(KERN_WARNING, ha, | ||
604 | "Firmware has been previously dumped (%p) -- ignoring " | ||
605 | "request...\n", ha->fw_dump); | ||
606 | goto qla2100_fw_dump_failed; | ||
607 | } | ||
608 | |||
609 | /* Allocate (large) dump buffer. */ | ||
610 | ha->fw_dump_order = get_order(sizeof(struct qla2100_fw_dump)); | ||
611 | ha->fw_dump = (struct qla2100_fw_dump *) __get_free_pages(GFP_ATOMIC, | ||
612 | ha->fw_dump_order); | ||
613 | if (ha->fw_dump == NULL) { | ||
614 | qla_printk(KERN_WARNING, ha, | ||
615 | "Unable to allocated memory for firmware dump (%d/%Zd).\n", | ||
616 | ha->fw_dump_order, sizeof(struct qla2100_fw_dump)); | ||
617 | goto qla2100_fw_dump_failed; | ||
618 | } | ||
619 | fw = ha->fw_dump; | ||
620 | |||
621 | rval = QLA_SUCCESS; | ||
622 | fw->hccr = RD_REG_WORD(®->hccr); | ||
623 | |||
624 | /* Pause RISC. */ | ||
625 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); | ||
626 | for (cnt = 30000; (RD_REG_WORD(®->hccr) & HCCR_RISC_PAUSE) == 0 && | ||
627 | rval == QLA_SUCCESS; cnt--) { | ||
628 | if (cnt) | ||
629 | udelay(100); | ||
630 | else | ||
631 | rval = QLA_FUNCTION_TIMEOUT; | ||
632 | } | ||
633 | if (rval == QLA_SUCCESS) { | ||
634 | dmp_reg = (uint16_t __iomem *)(reg + 0); | ||
635 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) | ||
636 | fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
637 | |||
638 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); | ||
639 | for (cnt = 0; cnt < ha->mbx_count; cnt++) { | ||
640 | if (cnt == 8) { | ||
641 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xe0); | ||
642 | } | ||
643 | fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
644 | } | ||
645 | |||
646 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20); | ||
647 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) | ||
648 | fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
649 | |||
650 | WRT_REG_WORD(®->ctrl_status, 0x00); | ||
651 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); | ||
652 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) | ||
653 | fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
654 | |||
655 | WRT_REG_WORD(®->pcr, 0x2000); | ||
656 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
657 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) | ||
658 | fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
659 | |||
660 | WRT_REG_WORD(®->pcr, 0x2100); | ||
661 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
662 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) | ||
663 | fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
664 | |||
665 | WRT_REG_WORD(®->pcr, 0x2200); | ||
666 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
667 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) | ||
668 | fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
669 | |||
670 | WRT_REG_WORD(®->pcr, 0x2300); | ||
671 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
672 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) | ||
673 | fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
674 | |||
675 | WRT_REG_WORD(®->pcr, 0x2400); | ||
676 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
677 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) | ||
678 | fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
679 | |||
680 | WRT_REG_WORD(®->pcr, 0x2500); | ||
681 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
682 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) | ||
683 | fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
684 | |||
685 | WRT_REG_WORD(®->pcr, 0x2600); | ||
686 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
687 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) | ||
688 | fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
689 | |||
690 | WRT_REG_WORD(®->pcr, 0x2700); | ||
691 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
692 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) | ||
693 | fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
694 | |||
695 | WRT_REG_WORD(®->ctrl_status, 0x10); | ||
696 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
697 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) | ||
698 | fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
699 | |||
700 | WRT_REG_WORD(®->ctrl_status, 0x20); | ||
701 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
702 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) | ||
703 | fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
704 | |||
705 | WRT_REG_WORD(®->ctrl_status, 0x30); | ||
706 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
707 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) | ||
708 | fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++); | ||
709 | |||
710 | /* Reset the ISP. */ | ||
711 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | ||
712 | } | ||
713 | |||
714 | for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 && | ||
715 | rval == QLA_SUCCESS; cnt--) { | ||
716 | if (cnt) | ||
717 | udelay(100); | ||
718 | else | ||
719 | rval = QLA_FUNCTION_TIMEOUT; | ||
720 | } | ||
721 | |||
722 | /* Pause RISC. */ | ||
723 | if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) && | ||
724 | (RD_REG_WORD(®->mctr) & (BIT_1 | BIT_0)) != 0))) { | ||
725 | |||
726 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); | ||
727 | for (cnt = 30000; | ||
728 | (RD_REG_WORD(®->hccr) & HCCR_RISC_PAUSE) == 0 && | ||
729 | rval == QLA_SUCCESS; cnt--) { | ||
730 | if (cnt) | ||
731 | udelay(100); | ||
732 | else | ||
733 | rval = QLA_FUNCTION_TIMEOUT; | ||
734 | } | ||
735 | if (rval == QLA_SUCCESS) { | ||
736 | /* Set memory configuration and timing. */ | ||
737 | if (IS_QLA2100(ha)) | ||
738 | WRT_REG_WORD(®->mctr, 0xf1); | ||
739 | else | ||
740 | WRT_REG_WORD(®->mctr, 0xf2); | ||
741 | RD_REG_WORD(®->mctr); /* PCI Posting. */ | ||
742 | |||
743 | /* Release RISC. */ | ||
744 | WRT_REG_WORD(®->hccr, HCCR_RELEASE_RISC); | ||
745 | } | ||
746 | } | ||
747 | |||
748 | if (rval == QLA_SUCCESS) { | ||
749 | /* Get RISC SRAM. */ | ||
750 | risc_address = 0x1000; | ||
751 | WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD); | ||
752 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
753 | } | ||
754 | for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS; | ||
755 | cnt++, risc_address++) { | ||
756 | WRT_MAILBOX_REG(ha, reg, 1, risc_address); | ||
757 | WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT); | ||
758 | |||
759 | for (timer = 6000000; timer != 0; timer--) { | ||
760 | /* Check for pending interrupts. */ | ||
761 | if (RD_REG_WORD(®->istatus) & ISR_RISC_INT) { | ||
762 | if (RD_REG_WORD(®->semaphore) & BIT_0) { | ||
763 | set_bit(MBX_INTERRUPT, | ||
764 | &ha->mbx_cmd_flags); | ||
765 | |||
766 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
767 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
768 | |||
769 | WRT_REG_WORD(®->semaphore, 0); | ||
770 | WRT_REG_WORD(®->hccr, | ||
771 | HCCR_CLR_RISC_INT); | ||
772 | RD_REG_WORD(®->hccr); | ||
773 | break; | ||
774 | } | ||
775 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | ||
776 | RD_REG_WORD(®->hccr); | ||
777 | } | ||
778 | udelay(5); | ||
779 | } | ||
780 | |||
781 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
782 | rval = mb0 & MBS_MASK; | ||
783 | fw->risc_ram[cnt] = mb2; | ||
784 | } else { | ||
785 | rval = QLA_FUNCTION_FAILED; | ||
786 | } | ||
787 | } | ||
788 | |||
789 | if (rval != QLA_SUCCESS) { | ||
790 | qla_printk(KERN_WARNING, ha, | ||
791 | "Failed to dump firmware (%x)!!!\n", rval); | ||
792 | |||
793 | free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order); | ||
794 | ha->fw_dump = NULL; | ||
795 | } else { | ||
796 | qla_printk(KERN_INFO, ha, | ||
797 | "Firmware dump saved to temp buffer (%ld/%p).\n", | ||
798 | ha->host_no, ha->fw_dump); | ||
799 | } | ||
800 | |||
801 | qla2100_fw_dump_failed: | ||
802 | if (!hardware_locked) | ||
803 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
804 | } | ||
805 | |||
806 | /** | ||
807 | * qla2100_ascii_fw_dump() - Converts a binary firmware dump to ASCII. | ||
808 | * @ha: HA context | ||
809 | */ | ||
810 | void | ||
811 | qla2100_ascii_fw_dump(scsi_qla_host_t *ha) | ||
812 | { | ||
813 | uint32_t cnt; | ||
814 | char *uiter; | ||
815 | char fw_info[30]; | ||
816 | struct qla2100_fw_dump *fw; | ||
817 | |||
818 | uiter = ha->fw_dump_buffer; | ||
819 | fw = ha->fw_dump; | ||
820 | |||
821 | qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number, | ||
822 | qla2x00_get_fw_version_str(ha, fw_info)); | ||
823 | |||
824 | qla_uprintf(&uiter, "\n[==>BEG]\n"); | ||
825 | |||
826 | qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr); | ||
827 | |||
828 | qla_uprintf(&uiter, "PBIU Registers:"); | ||
829 | for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) { | ||
830 | if (cnt % 8 == 0) { | ||
831 | qla_uprintf(&uiter, "\n"); | ||
832 | } | ||
833 | qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]); | ||
834 | } | ||
835 | |||
836 | qla_uprintf(&uiter, "\n\nMailbox Registers:"); | ||
837 | for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) { | ||
838 | if (cnt % 8 == 0) { | ||
839 | qla_uprintf(&uiter, "\n"); | ||
840 | } | ||
841 | qla_uprintf(&uiter, "%04x ", fw->mailbox_reg[cnt]); | ||
842 | } | ||
843 | |||
844 | qla_uprintf(&uiter, "\n\nDMA Registers:"); | ||
845 | for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) { | ||
846 | if (cnt % 8 == 0) { | ||
847 | qla_uprintf(&uiter, "\n"); | ||
848 | } | ||
849 | qla_uprintf(&uiter, "%04x ", fw->dma_reg[cnt]); | ||
850 | } | ||
851 | |||
852 | qla_uprintf(&uiter, "\n\nRISC Hardware Registers:"); | ||
853 | for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) { | ||
854 | if (cnt % 8 == 0) { | ||
855 | qla_uprintf(&uiter, "\n"); | ||
856 | } | ||
857 | qla_uprintf(&uiter, "%04x ", fw->risc_hdw_reg[cnt]); | ||
858 | } | ||
859 | |||
860 | qla_uprintf(&uiter, "\n\nRISC GP0 Registers:"); | ||
861 | for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) { | ||
862 | if (cnt % 8 == 0) { | ||
863 | qla_uprintf(&uiter, "\n"); | ||
864 | } | ||
865 | qla_uprintf(&uiter, "%04x ", fw->risc_gp0_reg[cnt]); | ||
866 | } | ||
867 | |||
868 | qla_uprintf(&uiter, "\n\nRISC GP1 Registers:"); | ||
869 | for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) { | ||
870 | if (cnt % 8 == 0) { | ||
871 | qla_uprintf(&uiter, "\n"); | ||
872 | } | ||
873 | qla_uprintf(&uiter, "%04x ", fw->risc_gp1_reg[cnt]); | ||
874 | } | ||
875 | |||
876 | qla_uprintf(&uiter, "\n\nRISC GP2 Registers:"); | ||
877 | for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) { | ||
878 | if (cnt % 8 == 0) { | ||
879 | qla_uprintf(&uiter, "\n"); | ||
880 | } | ||
881 | qla_uprintf(&uiter, "%04x ", fw->risc_gp2_reg[cnt]); | ||
882 | } | ||
883 | |||
884 | qla_uprintf(&uiter, "\n\nRISC GP3 Registers:"); | ||
885 | for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) { | ||
886 | if (cnt % 8 == 0) { | ||
887 | qla_uprintf(&uiter, "\n"); | ||
888 | } | ||
889 | qla_uprintf(&uiter, "%04x ", fw->risc_gp3_reg[cnt]); | ||
890 | } | ||
891 | |||
892 | qla_uprintf(&uiter, "\n\nRISC GP4 Registers:"); | ||
893 | for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) { | ||
894 | if (cnt % 8 == 0) { | ||
895 | qla_uprintf(&uiter, "\n"); | ||
896 | } | ||
897 | qla_uprintf(&uiter, "%04x ", fw->risc_gp4_reg[cnt]); | ||
898 | } | ||
899 | |||
900 | qla_uprintf(&uiter, "\n\nRISC GP5 Registers:"); | ||
901 | for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) { | ||
902 | if (cnt % 8 == 0) { | ||
903 | qla_uprintf(&uiter, "\n"); | ||
904 | } | ||
905 | qla_uprintf(&uiter, "%04x ", fw->risc_gp5_reg[cnt]); | ||
906 | } | ||
907 | |||
908 | qla_uprintf(&uiter, "\n\nRISC GP6 Registers:"); | ||
909 | for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) { | ||
910 | if (cnt % 8 == 0) { | ||
911 | qla_uprintf(&uiter, "\n"); | ||
912 | } | ||
913 | qla_uprintf(&uiter, "%04x ", fw->risc_gp6_reg[cnt]); | ||
914 | } | ||
915 | |||
916 | qla_uprintf(&uiter, "\n\nRISC GP7 Registers:"); | ||
917 | for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) { | ||
918 | if (cnt % 8 == 0) { | ||
919 | qla_uprintf(&uiter, "\n"); | ||
920 | } | ||
921 | qla_uprintf(&uiter, "%04x ", fw->risc_gp7_reg[cnt]); | ||
922 | } | ||
923 | |||
924 | qla_uprintf(&uiter, "\n\nFrame Buffer Hardware Registers:"); | ||
925 | for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) { | ||
926 | if (cnt % 8 == 0) { | ||
927 | qla_uprintf(&uiter, "\n"); | ||
928 | } | ||
929 | qla_uprintf(&uiter, "%04x ", fw->frame_buf_hdw_reg[cnt]); | ||
930 | } | ||
931 | |||
932 | qla_uprintf(&uiter, "\n\nFPM B0 Registers:"); | ||
933 | for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) { | ||
934 | if (cnt % 8 == 0) { | ||
935 | qla_uprintf(&uiter, "\n"); | ||
936 | } | ||
937 | qla_uprintf(&uiter, "%04x ", fw->fpm_b0_reg[cnt]); | ||
938 | } | ||
939 | |||
940 | qla_uprintf(&uiter, "\n\nFPM B1 Registers:"); | ||
941 | for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) { | ||
942 | if (cnt % 8 == 0) { | ||
943 | qla_uprintf(&uiter, "\n"); | ||
944 | } | ||
945 | qla_uprintf(&uiter, "%04x ", fw->fpm_b1_reg[cnt]); | ||
946 | } | ||
947 | |||
948 | qla_uprintf(&uiter, "\n\nRISC SRAM:"); | ||
949 | for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) { | ||
950 | if (cnt % 8 == 0) { | ||
951 | qla_uprintf(&uiter, "\n%04x: ", cnt + 0x1000); | ||
952 | } | ||
953 | qla_uprintf(&uiter, "%04x ", fw->risc_ram[cnt]); | ||
954 | } | ||
955 | |||
956 | qla_uprintf(&uiter, "\n\n[<==END] ISP Debug Dump."); | ||
957 | |||
958 | return; | ||
959 | } | ||
960 | |||
961 | static int | ||
962 | qla_uprintf(char **uiter, char *fmt, ...) | ||
963 | { | ||
964 | int iter, len; | ||
965 | char buf[128]; | ||
966 | va_list args; | ||
967 | |||
968 | va_start(args, fmt); | ||
969 | len = vsprintf(buf, fmt, args); | ||
970 | va_end(args); | ||
971 | |||
972 | for (iter = 0; iter < len; iter++, *uiter += 1) | ||
973 | *uiter[0] = buf[iter]; | ||
974 | |||
975 | return (len); | ||
976 | } | ||
977 | |||
978 | //FIXME | ||
979 | |||
980 | /****************************************************************************/ | ||
981 | /* Driver Debug Functions. */ | ||
982 | /****************************************************************************/ | ||
983 | |||
984 | void | ||
985 | qla2x00_dump_regs(scsi_qla_host_t *ha) | ||
986 | { | ||
987 | device_reg_t __iomem *reg = ha->iobase; | ||
988 | |||
989 | printk("Mailbox registers:\n"); | ||
990 | printk("scsi(%ld): mbox 0 0x%04x \n", | ||
991 | ha->host_no, RD_MAILBOX_REG(ha, reg, 0)); | ||
992 | printk("scsi(%ld): mbox 1 0x%04x \n", | ||
993 | ha->host_no, RD_MAILBOX_REG(ha, reg, 1)); | ||
994 | printk("scsi(%ld): mbox 2 0x%04x \n", | ||
995 | ha->host_no, RD_MAILBOX_REG(ha, reg, 2)); | ||
996 | printk("scsi(%ld): mbox 3 0x%04x \n", | ||
997 | ha->host_no, RD_MAILBOX_REG(ha, reg, 3)); | ||
998 | printk("scsi(%ld): mbox 4 0x%04x \n", | ||
999 | ha->host_no, RD_MAILBOX_REG(ha, reg, 4)); | ||
1000 | printk("scsi(%ld): mbox 5 0x%04x \n", | ||
1001 | ha->host_no, RD_MAILBOX_REG(ha, reg, 5)); | ||
1002 | } | ||
1003 | |||
1004 | |||
1005 | void | ||
1006 | qla2x00_dump_buffer(uint8_t * b, uint32_t size) | ||
1007 | { | ||
1008 | uint32_t cnt; | ||
1009 | uint8_t c; | ||
1010 | |||
1011 | printk(" 0 1 2 3 4 5 6 7 8 9 " | ||
1012 | "Ah Bh Ch Dh Eh Fh\n"); | ||
1013 | printk("----------------------------------------" | ||
1014 | "----------------------\n"); | ||
1015 | |||
1016 | for (cnt = 0; cnt < size;) { | ||
1017 | c = *b++; | ||
1018 | printk("%02x",(uint32_t) c); | ||
1019 | cnt++; | ||
1020 | if (!(cnt % 16)) | ||
1021 | printk("\n"); | ||
1022 | else | ||
1023 | printk(" "); | ||
1024 | } | ||
1025 | if (cnt % 16) | ||
1026 | printk("\n"); | ||
1027 | } | ||
1028 | |||
1029 | /************************************************************************** | ||
1030 | * qla2x00_print_scsi_cmd | ||
1031 | * Dumps out info about the scsi cmd and srb. | ||
1032 | * Input | ||
1033 | * cmd : struct scsi_cmnd | ||
1034 | **************************************************************************/ | ||
1035 | void | ||
1036 | qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd) | ||
1037 | { | ||
1038 | int i; | ||
1039 | struct scsi_qla_host *ha; | ||
1040 | srb_t *sp; | ||
1041 | |||
1042 | ha = (struct scsi_qla_host *)cmd->device->host->hostdata; | ||
1043 | |||
1044 | sp = (srb_t *) cmd->SCp.ptr; | ||
1045 | printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble); | ||
1046 | printk(" chan=0x%02x, target=0x%02x, lun=0x%02x, cmd_len=0x%02x\n", | ||
1047 | cmd->device->channel, cmd->device->id, cmd->device->lun, | ||
1048 | cmd->cmd_len); | ||
1049 | printk(" CDB: "); | ||
1050 | for (i = 0; i < cmd->cmd_len; i++) { | ||
1051 | printk("0x%02x ", cmd->cmnd[i]); | ||
1052 | } | ||
1053 | printk("\n seg_cnt=%d, allowed=%d, retries=%d, " | ||
1054 | "serial_number_at_timeout=0x%lx\n", | ||
1055 | cmd->use_sg, cmd->allowed, cmd->retries, | ||
1056 | cmd->serial_number_at_timeout); | ||
1057 | printk(" request buffer=0x%p, request buffer len=0x%x\n", | ||
1058 | cmd->request_buffer, cmd->request_bufflen); | ||
1059 | printk(" tag=%d, transfersize=0x%x\n", | ||
1060 | cmd->tag, cmd->transfersize); | ||
1061 | printk(" serial_number=%lx, SP=%p\n", cmd->serial_number, sp); | ||
1062 | printk(" data direction=%d\n", cmd->sc_data_direction); | ||
1063 | |||
1064 | if (!sp) | ||
1065 | return; | ||
1066 | |||
1067 | printk(" sp flags=0x%x\n", sp->flags); | ||
1068 | printk(" r_start=0x%lx, u_start=0x%lx, f_start=0x%lx, state=%d\n", | ||
1069 | sp->r_start, sp->u_start, sp->f_start, sp->state); | ||
1070 | |||
1071 | printk(" e_start= 0x%lx, ext_history=%d, fo retry=%d, loopid=%x, " | ||
1072 | "port path=%d\n", sp->e_start, sp->ext_history, sp->fo_retry_cnt, | ||
1073 | sp->lun_queue->fclun->fcport->loop_id, | ||
1074 | sp->lun_queue->fclun->fcport->cur_path); | ||
1075 | } | ||
1076 | |||
1077 | #if defined(QL_DEBUG_ROUTINES) | ||
1078 | /* | ||
1079 | * qla2x00_formatted_dump_buffer | ||
1080 | * Prints string plus buffer. | ||
1081 | * | ||
1082 | * Input: | ||
1083 | * string = Null terminated string (no newline at end). | ||
1084 | * buffer = buffer address. | ||
1085 | * wd_size = word size 8, 16, 32 or 64 bits | ||
1086 | * count = number of words. | ||
1087 | */ | ||
1088 | void | ||
1089 | qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer, | ||
1090 | uint8_t wd_size, uint32_t count) | ||
1091 | { | ||
1092 | uint32_t cnt; | ||
1093 | uint16_t *buf16; | ||
1094 | uint32_t *buf32; | ||
1095 | |||
1096 | if (strcmp(string, "") != 0) | ||
1097 | printk("%s\n",string); | ||
1098 | |||
1099 | switch (wd_size) { | ||
1100 | case 8: | ||
1101 | printk(" 0 1 2 3 4 5 6 7 " | ||
1102 | "8 9 Ah Bh Ch Dh Eh Fh\n"); | ||
1103 | printk("-----------------------------------------" | ||
1104 | "-------------------------------------\n"); | ||
1105 | |||
1106 | for (cnt = 1; cnt <= count; cnt++, buffer++) { | ||
1107 | printk("%02x",*buffer); | ||
1108 | if (cnt % 16 == 0) | ||
1109 | printk("\n"); | ||
1110 | else | ||
1111 | printk(" "); | ||
1112 | } | ||
1113 | if (cnt % 16 != 0) | ||
1114 | printk("\n"); | ||
1115 | break; | ||
1116 | case 16: | ||
1117 | printk(" 0 2 4 6 8 Ah " | ||
1118 | " Ch Eh\n"); | ||
1119 | printk("-----------------------------------------" | ||
1120 | "-------------\n"); | ||
1121 | |||
1122 | buf16 = (uint16_t *) buffer; | ||
1123 | for (cnt = 1; cnt <= count; cnt++, buf16++) { | ||
1124 | printk("%4x",*buf16); | ||
1125 | |||
1126 | if (cnt % 8 == 0) | ||
1127 | printk("\n"); | ||
1128 | else if (*buf16 < 10) | ||
1129 | printk(" "); | ||
1130 | else | ||
1131 | printk(" "); | ||
1132 | } | ||
1133 | if (cnt % 8 != 0) | ||
1134 | printk("\n"); | ||
1135 | break; | ||
1136 | case 32: | ||
1137 | printk(" 0 4 8 Ch\n"); | ||
1138 | printk("------------------------------------------\n"); | ||
1139 | |||
1140 | buf32 = (uint32_t *) buffer; | ||
1141 | for (cnt = 1; cnt <= count; cnt++, buf32++) { | ||
1142 | printk("%8x", *buf32); | ||
1143 | |||
1144 | if (cnt % 4 == 0) | ||
1145 | printk("\n"); | ||
1146 | else if (*buf32 < 10) | ||
1147 | printk(" "); | ||
1148 | else | ||
1149 | printk(" "); | ||
1150 | } | ||
1151 | if (cnt % 4 != 0) | ||
1152 | printk("\n"); | ||
1153 | break; | ||
1154 | default: | ||
1155 | break; | ||
1156 | } | ||
1157 | } | ||
1158 | #endif | ||