diff options
| author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2008-04-24 18:21:22 -0400 |
|---|---|---|
| committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-27 13:19:57 -0400 |
| commit | c5722708c236b51286651b8c07855f764239453b (patch) | |
| tree | f721837b7b807f3e601467fb7292f0cf6bdacd8a | |
| parent | 6fe07aaffbf086a0ce9134ef27ce4a8921ff5947 (diff) | |
[SCSI] qla2xxx: Collapse RISC-RAM retrieval code during a firmware-dump.
Use the more efficient read-DMA'ble-buffer mailbox commands
rather than reading a single word/dword at a time. We also
remove a bulk of the duplicate mailbox command-handling codes in
favor of more generic read-memory() routines (qla2xxx_dump_ram()
and qla24xx_dump_ram()).
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 394 |
1 files changed, 143 insertions, 251 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 9d12d9f26209..cbef785765cf 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
| @@ -38,78 +38,38 @@ qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr) | |||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | static int | 40 | static int |
| 41 | qla24xx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, | 41 | qla24xx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint32_t *ram, |
| 42 | uint32_t cram_size, uint32_t *ext_mem, void **nxt) | 42 | uint32_t ram_dwords, void **nxt) |
| 43 | { | 43 | { |
| 44 | int rval; | 44 | int rval; |
| 45 | uint32_t cnt, stat, timer, risc_address, ext_mem_cnt; | 45 | uint32_t cnt, stat, timer, dwords, idx; |
| 46 | uint16_t mb[4]; | 46 | uint16_t mb0; |
| 47 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 47 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
| 48 | dma_addr_t dump_dma = ha->gid_list_dma; | ||
| 49 | uint32_t *dump = (uint32_t *)ha->gid_list; | ||
| 48 | 50 | ||
| 49 | rval = QLA_SUCCESS; | 51 | rval = QLA_SUCCESS; |
| 50 | risc_address = ext_mem_cnt = 0; | 52 | mb0 = 0; |
| 51 | memset(mb, 0, sizeof(mb)); | ||
| 52 | 53 | ||
| 53 | /* Code RAM. */ | 54 | WRT_REG_WORD(®->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED); |
| 54 | risc_address = 0x20000; | ||
| 55 | WRT_REG_WORD(®->mailbox0, MBC_READ_RAM_EXTENDED); | ||
| 56 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 55 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
| 57 | 56 | ||
| 58 | for (cnt = 0; cnt < cram_size / 4 && rval == QLA_SUCCESS; | 57 | dwords = GID_LIST_SIZE / 4; |
| 59 | cnt++, risc_address++) { | 58 | for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS; |
| 60 | WRT_REG_WORD(®->mailbox1, LSW(risc_address)); | 59 | cnt += dwords, addr += dwords) { |
| 61 | WRT_REG_WORD(®->mailbox8, MSW(risc_address)); | 60 | if (cnt + dwords > ram_dwords) |
| 62 | RD_REG_WORD(®->mailbox8); | 61 | dwords = ram_dwords - cnt; |
| 63 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | ||
| 64 | |||
| 65 | for (timer = 6000000; timer; timer--) { | ||
| 66 | /* Check for pending interrupts. */ | ||
| 67 | stat = RD_REG_DWORD(®->host_status); | ||
| 68 | if (stat & HSRX_RISC_INT) { | ||
| 69 | stat &= 0xff; | ||
| 70 | 62 | ||
| 71 | if (stat == 0x1 || stat == 0x2 || | 63 | WRT_REG_WORD(®->mailbox1, LSW(addr)); |
| 72 | stat == 0x10 || stat == 0x11) { | 64 | WRT_REG_WORD(®->mailbox8, MSW(addr)); |
| 73 | set_bit(MBX_INTERRUPT, | ||
| 74 | &ha->mbx_cmd_flags); | ||
| 75 | 65 | ||
| 76 | mb[0] = RD_REG_WORD(®->mailbox0); | 66 | WRT_REG_WORD(®->mailbox2, MSW(dump_dma)); |
| 77 | mb[2] = RD_REG_WORD(®->mailbox2); | 67 | WRT_REG_WORD(®->mailbox3, LSW(dump_dma)); |
| 78 | mb[3] = RD_REG_WORD(®->mailbox3); | 68 | WRT_REG_WORD(®->mailbox6, MSW(MSD(dump_dma))); |
| 69 | WRT_REG_WORD(®->mailbox7, LSW(MSD(dump_dma))); | ||
| 79 | 70 | ||
| 80 | WRT_REG_DWORD(®->hccr, | 71 | WRT_REG_WORD(®->mailbox4, MSW(dwords)); |
| 81 | HCCRX_CLR_RISC_INT); | 72 | WRT_REG_WORD(®->mailbox5, LSW(dwords)); |
| 82 | RD_REG_DWORD(®->hccr); | ||
| 83 | break; | ||
| 84 | } | ||
| 85 | |||
| 86 | /* Clear this intr; it wasn't a mailbox intr */ | ||
| 87 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
| 88 | RD_REG_DWORD(®->hccr); | ||
| 89 | } | ||
| 90 | udelay(5); | ||
| 91 | } | ||
| 92 | |||
| 93 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
| 94 | rval = mb[0] & MBS_MASK; | ||
| 95 | code_ram[cnt] = htonl((mb[3] << 16) | mb[2]); | ||
| 96 | } else { | ||
| 97 | rval = QLA_FUNCTION_FAILED; | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | if (rval == QLA_SUCCESS) { | ||
| 102 | /* External Memory. */ | ||
| 103 | risc_address = 0x100000; | ||
| 104 | ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1; | ||
| 105 | WRT_REG_WORD(®->mailbox0, MBC_READ_RAM_EXTENDED); | ||
| 106 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 107 | } | ||
| 108 | for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS; | ||
| 109 | cnt++, risc_address++) { | ||
| 110 | WRT_REG_WORD(®->mailbox1, LSW(risc_address)); | ||
| 111 | WRT_REG_WORD(®->mailbox8, MSW(risc_address)); | ||
| 112 | RD_REG_WORD(®->mailbox8); | ||
| 113 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | 73 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); |
| 114 | 74 | ||
| 115 | for (timer = 6000000; timer; timer--) { | 75 | for (timer = 6000000; timer; timer--) { |
| @@ -123,9 +83,7 @@ qla24xx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, | |||
| 123 | set_bit(MBX_INTERRUPT, | 83 | set_bit(MBX_INTERRUPT, |
| 124 | &ha->mbx_cmd_flags); | 84 | &ha->mbx_cmd_flags); |
| 125 | 85 | ||
| 126 | mb[0] = RD_REG_WORD(®->mailbox0); | 86 | mb0 = RD_REG_WORD(®->mailbox0); |
| 127 | mb[2] = RD_REG_WORD(®->mailbox2); | ||
| 128 | mb[3] = RD_REG_WORD(®->mailbox3); | ||
| 129 | 87 | ||
| 130 | WRT_REG_DWORD(®->hccr, | 88 | WRT_REG_DWORD(®->hccr, |
| 131 | HCCRX_CLR_RISC_INT); | 89 | HCCRX_CLR_RISC_INT); |
| @@ -141,17 +99,34 @@ qla24xx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, | |||
| 141 | } | 99 | } |
| 142 | 100 | ||
| 143 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 101 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
| 144 | rval = mb[0] & MBS_MASK; | 102 | rval = mb0 & MBS_MASK; |
| 145 | ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]); | 103 | for (idx = 0; idx < dwords; idx++) |
| 104 | ram[cnt + idx] = swab32(dump[idx]); | ||
| 146 | } else { | 105 | } else { |
| 147 | rval = QLA_FUNCTION_FAILED; | 106 | rval = QLA_FUNCTION_FAILED; |
| 148 | } | 107 | } |
| 149 | } | 108 | } |
| 150 | 109 | ||
| 151 | *nxt = rval == QLA_SUCCESS ? &ext_mem[cnt]: NULL; | 110 | *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL; |
| 152 | return rval; | 111 | return rval; |
| 153 | } | 112 | } |
| 154 | 113 | ||
| 114 | static int | ||
| 115 | qla24xx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, | ||
| 116 | uint32_t cram_size, void **nxt) | ||
| 117 | { | ||
| 118 | int rval; | ||
| 119 | |||
| 120 | /* Code RAM. */ | ||
| 121 | rval = qla24xx_dump_ram(ha, 0x20000, code_ram, cram_size / 4, nxt); | ||
| 122 | if (rval != QLA_SUCCESS) | ||
| 123 | return rval; | ||
| 124 | |||
| 125 | /* External Memory. */ | ||
| 126 | return qla24xx_dump_ram(ha, 0x100000, *nxt, | ||
| 127 | ha->fw_memory_size - 0x100000 + 1, nxt); | ||
| 128 | } | ||
| 129 | |||
| 155 | static uint32_t * | 130 | static uint32_t * |
| 156 | qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase, | 131 | qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase, |
| 157 | uint32_t count, uint32_t *buf) | 132 | uint32_t count, uint32_t *buf) |
| @@ -239,6 +214,90 @@ qla24xx_soft_reset(scsi_qla_host_t *ha) | |||
| 239 | return rval; | 214 | return rval; |
| 240 | } | 215 | } |
| 241 | 216 | ||
| 217 | static int | ||
| 218 | qla2xxx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint16_t *ram, | ||
| 219 | uint16_t ram_words, void **nxt) | ||
| 220 | { | ||
| 221 | int rval; | ||
| 222 | uint32_t cnt, stat, timer, words, idx; | ||
| 223 | uint16_t mb0; | ||
| 224 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
| 225 | dma_addr_t dump_dma = ha->gid_list_dma; | ||
| 226 | uint16_t *dump = (uint16_t *)ha->gid_list; | ||
| 227 | |||
| 228 | rval = QLA_SUCCESS; | ||
| 229 | mb0 = 0; | ||
| 230 | |||
| 231 | WRT_MAILBOX_REG(ha, reg, 0, MBC_DUMP_RISC_RAM_EXTENDED); | ||
| 232 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 233 | |||
| 234 | words = GID_LIST_SIZE / 2; | ||
| 235 | for (cnt = 0; cnt < ram_words && rval == QLA_SUCCESS; | ||
| 236 | cnt += words, addr += words) { | ||
| 237 | if (cnt + words > ram_words) | ||
| 238 | words = ram_words - cnt; | ||
| 239 | |||
| 240 | WRT_MAILBOX_REG(ha, reg, 1, LSW(addr)); | ||
| 241 | WRT_MAILBOX_REG(ha, reg, 8, MSW(addr)); | ||
| 242 | |||
| 243 | WRT_MAILBOX_REG(ha, reg, 2, MSW(dump_dma)); | ||
| 244 | WRT_MAILBOX_REG(ha, reg, 3, LSW(dump_dma)); | ||
| 245 | WRT_MAILBOX_REG(ha, reg, 6, MSW(MSD(dump_dma))); | ||
| 246 | WRT_MAILBOX_REG(ha, reg, 7, LSW(MSD(dump_dma))); | ||
| 247 | |||
| 248 | WRT_MAILBOX_REG(ha, reg, 4, words); | ||
| 249 | WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT); | ||
| 250 | |||
| 251 | for (timer = 6000000; timer; timer--) { | ||
| 252 | /* Check for pending interrupts. */ | ||
| 253 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | ||
| 254 | if (stat & HSR_RISC_INT) { | ||
| 255 | stat &= 0xff; | ||
| 256 | |||
| 257 | if (stat == 0x1 || stat == 0x2) { | ||
| 258 | set_bit(MBX_INTERRUPT, | ||
| 259 | &ha->mbx_cmd_flags); | ||
| 260 | |||
| 261 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
| 262 | |||
| 263 | /* Release mailbox registers. */ | ||
| 264 | WRT_REG_WORD(®->semaphore, 0); | ||
| 265 | WRT_REG_WORD(®->hccr, | ||
| 266 | HCCR_CLR_RISC_INT); | ||
| 267 | RD_REG_WORD(®->hccr); | ||
| 268 | break; | ||
| 269 | } else if (stat == 0x10 || stat == 0x11) { | ||
| 270 | set_bit(MBX_INTERRUPT, | ||
| 271 | &ha->mbx_cmd_flags); | ||
| 272 | |||
| 273 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
| 274 | |||
| 275 | WRT_REG_WORD(®->hccr, | ||
| 276 | HCCR_CLR_RISC_INT); | ||
| 277 | RD_REG_WORD(®->hccr); | ||
| 278 | break; | ||
| 279 | } | ||
| 280 | |||
| 281 | /* clear this intr; it wasn't a mailbox intr */ | ||
| 282 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | ||
| 283 | RD_REG_WORD(®->hccr); | ||
| 284 | } | ||
| 285 | udelay(5); | ||
| 286 | } | ||
| 287 | |||
| 288 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
| 289 | rval = mb0 & MBS_MASK; | ||
| 290 | for (idx = 0; idx < words; idx++) | ||
| 291 | ram[cnt + idx] = swab16(dump[idx]); | ||
| 292 | } else { | ||
| 293 | rval = QLA_FUNCTION_FAILED; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL; | ||
| 298 | return rval; | ||
| 299 | } | ||
| 300 | |||
| 242 | static inline void | 301 | static inline void |
| 243 | qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count, | 302 | qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count, |
| 244 | uint16_t *buf) | 303 | uint16_t *buf) |
| @@ -258,19 +317,14 @@ void | |||
| 258 | qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | 317 | qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) |
| 259 | { | 318 | { |
| 260 | int rval; | 319 | int rval; |
| 261 | uint32_t cnt, timer; | 320 | uint32_t cnt; |
| 262 | uint32_t risc_address; | ||
| 263 | uint16_t mb0, mb2; | ||
| 264 | 321 | ||
| 265 | uint32_t stat; | ||
| 266 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 322 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
| 267 | uint16_t __iomem *dmp_reg; | 323 | uint16_t __iomem *dmp_reg; |
| 268 | unsigned long flags; | 324 | unsigned long flags; |
| 269 | struct qla2300_fw_dump *fw; | 325 | struct qla2300_fw_dump *fw; |
| 270 | uint32_t data_ram_cnt; | 326 | void *nxt; |
| 271 | 327 | ||
| 272 | risc_address = data_ram_cnt = 0; | ||
| 273 | mb0 = mb2 = 0; | ||
| 274 | flags = 0; | 328 | flags = 0; |
| 275 | 329 | ||
| 276 | if (!hardware_locked) | 330 | if (!hardware_locked) |
| @@ -388,185 +442,23 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
| 388 | } | 442 | } |
| 389 | } | 443 | } |
| 390 | 444 | ||
| 391 | if (rval == QLA_SUCCESS) { | 445 | /* Get RISC SRAM. */ |
| 392 | /* Get RISC SRAM. */ | 446 | if (rval == QLA_SUCCESS) |
| 393 | risc_address = 0x800; | 447 | rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram, |
| 394 | WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD); | 448 | sizeof(fw->risc_ram) / 2, &nxt); |
| 395 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 396 | } | ||
| 397 | for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS; | ||
| 398 | cnt++, risc_address++) { | ||
| 399 | WRT_MAILBOX_REG(ha, reg, 1, (uint16_t)risc_address); | ||
| 400 | WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT); | ||
| 401 | |||
| 402 | for (timer = 6000000; timer; timer--) { | ||
| 403 | /* Check for pending interrupts. */ | ||
| 404 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | ||
| 405 | if (stat & HSR_RISC_INT) { | ||
| 406 | stat &= 0xff; | ||
| 407 | |||
| 408 | if (stat == 0x1 || stat == 0x2) { | ||
| 409 | set_bit(MBX_INTERRUPT, | ||
| 410 | &ha->mbx_cmd_flags); | ||
| 411 | |||
| 412 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
| 413 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
| 414 | |||
| 415 | /* Release mailbox registers. */ | ||
| 416 | WRT_REG_WORD(®->semaphore, 0); | ||
| 417 | WRT_REG_WORD(®->hccr, | ||
| 418 | HCCR_CLR_RISC_INT); | ||
| 419 | RD_REG_WORD(®->hccr); | ||
| 420 | break; | ||
| 421 | } else if (stat == 0x10 || stat == 0x11) { | ||
| 422 | set_bit(MBX_INTERRUPT, | ||
| 423 | &ha->mbx_cmd_flags); | ||
| 424 | |||
| 425 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
| 426 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
| 427 | |||
| 428 | WRT_REG_WORD(®->hccr, | ||
| 429 | HCCR_CLR_RISC_INT); | ||
| 430 | RD_REG_WORD(®->hccr); | ||
| 431 | break; | ||
| 432 | } | ||
| 433 | |||
| 434 | /* clear this intr; it wasn't a mailbox intr */ | ||
| 435 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | ||
| 436 | RD_REG_WORD(®->hccr); | ||
| 437 | } | ||
| 438 | udelay(5); | ||
| 439 | } | ||
| 440 | |||
| 441 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
| 442 | rval = mb0 & MBS_MASK; | ||
| 443 | fw->risc_ram[cnt] = htons(mb2); | ||
| 444 | } else { | ||
| 445 | rval = QLA_FUNCTION_FAILED; | ||
| 446 | } | ||
| 447 | } | ||
| 448 | |||
| 449 | if (rval == QLA_SUCCESS) { | ||
| 450 | /* Get stack SRAM. */ | ||
| 451 | risc_address = 0x10000; | ||
| 452 | WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED); | ||
| 453 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 454 | } | ||
| 455 | for (cnt = 0; cnt < sizeof(fw->stack_ram) / 2 && rval == QLA_SUCCESS; | ||
| 456 | cnt++, risc_address++) { | ||
| 457 | WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address)); | ||
| 458 | WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address)); | ||
| 459 | WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT); | ||
| 460 | |||
| 461 | for (timer = 6000000; timer; timer--) { | ||
| 462 | /* Check for pending interrupts. */ | ||
| 463 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | ||
| 464 | if (stat & HSR_RISC_INT) { | ||
| 465 | stat &= 0xff; | ||
| 466 | |||
| 467 | if (stat == 0x1 || stat == 0x2) { | ||
| 468 | set_bit(MBX_INTERRUPT, | ||
| 469 | &ha->mbx_cmd_flags); | ||
| 470 | |||
| 471 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
| 472 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
| 473 | |||
| 474 | /* Release mailbox registers. */ | ||
| 475 | WRT_REG_WORD(®->semaphore, 0); | ||
| 476 | WRT_REG_WORD(®->hccr, | ||
| 477 | HCCR_CLR_RISC_INT); | ||
| 478 | RD_REG_WORD(®->hccr); | ||
| 479 | break; | ||
| 480 | } else if (stat == 0x10 || stat == 0x11) { | ||
| 481 | set_bit(MBX_INTERRUPT, | ||
| 482 | &ha->mbx_cmd_flags); | ||
| 483 | |||
| 484 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
| 485 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
| 486 | |||
| 487 | WRT_REG_WORD(®->hccr, | ||
| 488 | HCCR_CLR_RISC_INT); | ||
| 489 | RD_REG_WORD(®->hccr); | ||
| 490 | break; | ||
| 491 | } | ||
| 492 | |||
| 493 | /* clear this intr; it wasn't a mailbox intr */ | ||
| 494 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | ||
| 495 | RD_REG_WORD(®->hccr); | ||
| 496 | } | ||
| 497 | udelay(5); | ||
| 498 | } | ||
| 499 | |||
| 500 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
| 501 | rval = mb0 & MBS_MASK; | ||
| 502 | fw->stack_ram[cnt] = htons(mb2); | ||
| 503 | } else { | ||
| 504 | rval = QLA_FUNCTION_FAILED; | ||
| 505 | } | ||
| 506 | } | ||
| 507 | |||
| 508 | if (rval == QLA_SUCCESS) { | ||
| 509 | /* Get data SRAM. */ | ||
| 510 | risc_address = 0x11000; | ||
| 511 | data_ram_cnt = ha->fw_memory_size - risc_address + 1; | ||
| 512 | WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED); | ||
| 513 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 514 | } | ||
| 515 | for (cnt = 0; cnt < data_ram_cnt && rval == QLA_SUCCESS; | ||
| 516 | cnt++, risc_address++) { | ||
| 517 | WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address)); | ||
| 518 | WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address)); | ||
| 519 | WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT); | ||
| 520 | |||
| 521 | for (timer = 6000000; timer; timer--) { | ||
| 522 | /* Check for pending interrupts. */ | ||
| 523 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | ||
| 524 | if (stat & HSR_RISC_INT) { | ||
| 525 | stat &= 0xff; | ||
| 526 | |||
| 527 | if (stat == 0x1 || stat == 0x2) { | ||
| 528 | set_bit(MBX_INTERRUPT, | ||
| 529 | &ha->mbx_cmd_flags); | ||
| 530 | |||
| 531 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
| 532 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
| 533 | |||
| 534 | /* Release mailbox registers. */ | ||
| 535 | WRT_REG_WORD(®->semaphore, 0); | ||
| 536 | WRT_REG_WORD(®->hccr, | ||
| 537 | HCCR_CLR_RISC_INT); | ||
| 538 | RD_REG_WORD(®->hccr); | ||
| 539 | break; | ||
| 540 | } else if (stat == 0x10 || stat == 0x11) { | ||
| 541 | set_bit(MBX_INTERRUPT, | ||
| 542 | &ha->mbx_cmd_flags); | ||
| 543 | |||
| 544 | mb0 = RD_MAILBOX_REG(ha, reg, 0); | ||
| 545 | mb2 = RD_MAILBOX_REG(ha, reg, 2); | ||
| 546 | |||
| 547 | WRT_REG_WORD(®->hccr, | ||
| 548 | HCCR_CLR_RISC_INT); | ||
| 549 | RD_REG_WORD(®->hccr); | ||
| 550 | break; | ||
| 551 | } | ||
| 552 | 449 | ||
| 553 | /* clear this intr; it wasn't a mailbox intr */ | 450 | /* Get stack SRAM. */ |
| 554 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | 451 | if (rval == QLA_SUCCESS) |
| 555 | RD_REG_WORD(®->hccr); | 452 | rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram, |
| 556 | } | 453 | sizeof(fw->stack_ram) / 2, &nxt); |
| 557 | udelay(5); | ||
| 558 | } | ||
| 559 | 454 | ||
| 560 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 455 | /* Get data SRAM. */ |
| 561 | rval = mb0 & MBS_MASK; | 456 | if (rval == QLA_SUCCESS) |
| 562 | fw->data_ram[cnt] = htons(mb2); | 457 | rval = qla2xxx_dump_ram(ha, 0x11000, fw->data_ram, |
| 563 | } else { | 458 | ha->fw_memory_size - 0x11000 + 1, &nxt); |
| 564 | rval = QLA_FUNCTION_FAILED; | ||
| 565 | } | ||
| 566 | } | ||
| 567 | 459 | ||
| 568 | if (rval == QLA_SUCCESS) | 460 | if (rval == QLA_SUCCESS) |
| 569 | qla2xxx_copy_queues(ha, &fw->data_ram[cnt]); | 461 | qla2xxx_copy_queues(ha, nxt); |
| 570 | 462 | ||
| 571 | if (rval != QLA_SUCCESS) { | 463 | if (rval != QLA_SUCCESS) { |
| 572 | qla_printk(KERN_WARNING, ha, | 464 | qla_printk(KERN_WARNING, ha, |
| @@ -1010,7 +902,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
| 1010 | goto qla24xx_fw_dump_failed_0; | 902 | goto qla24xx_fw_dump_failed_0; |
| 1011 | 903 | ||
| 1012 | rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), | 904 | rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), |
| 1013 | fw->ext_mem, &nxt); | 905 | &nxt); |
| 1014 | if (rval != QLA_SUCCESS) | 906 | if (rval != QLA_SUCCESS) |
| 1015 | goto qla24xx_fw_dump_failed_0; | 907 | goto qla24xx_fw_dump_failed_0; |
| 1016 | 908 | ||
| @@ -1318,7 +1210,7 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
| 1318 | goto qla25xx_fw_dump_failed_0; | 1210 | goto qla25xx_fw_dump_failed_0; |
| 1319 | 1211 | ||
| 1320 | rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), | 1212 | rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), |
| 1321 | fw->ext_mem, &nxt); | 1213 | &nxt); |
| 1322 | if (rval != QLA_SUCCESS) | 1214 | if (rval != QLA_SUCCESS) |
| 1323 | goto qla25xx_fw_dump_failed_0; | 1215 | goto qla25xx_fw_dump_failed_0; |
| 1324 | 1216 | ||
