}
static int
-qla24xx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram,
- uint32_t cram_size, uint32_t *ext_mem, void **nxt)
+qla24xx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint32_t *ram,
+ uint32_t ram_dwords, void **nxt)
{
int rval;
- uint32_t cnt, stat, timer, risc_address, ext_mem_cnt;
- uint16_t mb[4];
+ uint32_t cnt, stat, timer, dwords, idx;
+ uint16_t mb0;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+ dma_addr_t dump_dma = ha->gid_list_dma;
+ uint32_t *dump = (uint32_t *)ha->gid_list;
rval = QLA_SUCCESS;
- risc_address = ext_mem_cnt = 0;
- memset(mb, 0, sizeof(mb));
+ mb0 = 0;
- /* Code RAM. */
- risc_address = 0x20000;
- WRT_REG_WORD(®->mailbox0, MBC_READ_RAM_EXTENDED);
+ WRT_REG_WORD(®->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED);
clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
- for (cnt = 0; cnt < cram_size / 4 && rval == QLA_SUCCESS;
- cnt++, risc_address++) {
- WRT_REG_WORD(®->mailbox1, LSW(risc_address));
- WRT_REG_WORD(®->mailbox8, MSW(risc_address));
- RD_REG_WORD(®->mailbox8);
- WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT);
-
- for (timer = 6000000; timer; timer--) {
- /* Check for pending interrupts. */
- stat = RD_REG_DWORD(®->host_status);
- if (stat & HSRX_RISC_INT) {
- stat &= 0xff;
+ dwords = GID_LIST_SIZE / 4;
+ for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS;
+ cnt += dwords, addr += dwords) {
+ if (cnt + dwords > ram_dwords)
+ dwords = ram_dwords - cnt;
- if (stat == 0x1 || stat == 0x2 ||
- stat == 0x10 || stat == 0x11) {
- set_bit(MBX_INTERRUPT,
- &ha->mbx_cmd_flags);
+ WRT_REG_WORD(®->mailbox1, LSW(addr));
+ WRT_REG_WORD(®->mailbox8, MSW(addr));
- mb[0] = RD_REG_WORD(®->mailbox0);
- mb[2] = RD_REG_WORD(®->mailbox2);
- mb[3] = RD_REG_WORD(®->mailbox3);
+ WRT_REG_WORD(®->mailbox2, MSW(dump_dma));
+ WRT_REG_WORD(®->mailbox3, LSW(dump_dma));
+ WRT_REG_WORD(®->mailbox6, MSW(MSD(dump_dma)));
+ WRT_REG_WORD(®->mailbox7, LSW(MSD(dump_dma)));
- WRT_REG_DWORD(®->hccr,
- HCCRX_CLR_RISC_INT);
- RD_REG_DWORD(®->hccr);
- break;
- }
-
- /* Clear this intr; it wasn't a mailbox intr */
- WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT);
- RD_REG_DWORD(®->hccr);
- }
- udelay(5);
- }
-
- if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
- rval = mb[0] & MBS_MASK;
- code_ram[cnt] = htonl((mb[3] << 16) | mb[2]);
- } else {
- rval = QLA_FUNCTION_FAILED;
- }
- }
-
- if (rval == QLA_SUCCESS) {
- /* External Memory. */
- risc_address = 0x100000;
- ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1;
- WRT_REG_WORD(®->mailbox0, MBC_READ_RAM_EXTENDED);
- clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
- }
- for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS;
- cnt++, risc_address++) {
- WRT_REG_WORD(®->mailbox1, LSW(risc_address));
- WRT_REG_WORD(®->mailbox8, MSW(risc_address));
- RD_REG_WORD(®->mailbox8);
+ WRT_REG_WORD(®->mailbox4, MSW(dwords));
+ WRT_REG_WORD(®->mailbox5, LSW(dwords));
WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT);
for (timer = 6000000; timer; timer--) {
set_bit(MBX_INTERRUPT,
&ha->mbx_cmd_flags);
- mb[0] = RD_REG_WORD(®->mailbox0);
- mb[2] = RD_REG_WORD(®->mailbox2);
- mb[3] = RD_REG_WORD(®->mailbox3);
+ mb0 = RD_REG_WORD(®->mailbox0);
WRT_REG_DWORD(®->hccr,
HCCRX_CLR_RISC_INT);
}
if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
- rval = mb[0] & MBS_MASK;
- ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]);
+ rval = mb0 & MBS_MASK;
+ for (idx = 0; idx < dwords; idx++)
+ ram[cnt + idx] = swab32(dump[idx]);
} else {
rval = QLA_FUNCTION_FAILED;
}
}
- *nxt = rval == QLA_SUCCESS ? &ext_mem[cnt]: NULL;
+ *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL;
return rval;
}
+static int
+qla24xx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram,
+ uint32_t cram_size, void **nxt)
+{
+ int rval;
+
+ /* Code RAM. */
+ rval = qla24xx_dump_ram(ha, 0x20000, code_ram, cram_size / 4, nxt);
+ if (rval != QLA_SUCCESS)
+ return rval;
+
+ /* External Memory. */
+ return qla24xx_dump_ram(ha, 0x100000, *nxt,
+ ha->fw_memory_size - 0x100000 + 1, nxt);
+}
+
static uint32_t *
qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase,
uint32_t count, uint32_t *buf)
return rval;
}
+static int
+qla2xxx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint16_t *ram,
+ uint16_t ram_words, void **nxt)
+{
+ int rval;
+ uint32_t cnt, stat, timer, words, idx;
+ uint16_t mb0;
+ struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+ dma_addr_t dump_dma = ha->gid_list_dma;
+ uint16_t *dump = (uint16_t *)ha->gid_list;
+
+ rval = QLA_SUCCESS;
+ mb0 = 0;
+
+ WRT_MAILBOX_REG(ha, reg, 0, MBC_DUMP_RISC_RAM_EXTENDED);
+ clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+
+ words = GID_LIST_SIZE / 2;
+ for (cnt = 0; cnt < ram_words && rval == QLA_SUCCESS;
+ cnt += words, addr += words) {
+ if (cnt + words > ram_words)
+ words = ram_words - cnt;
+
+ WRT_MAILBOX_REG(ha, reg, 1, LSW(addr));
+ WRT_MAILBOX_REG(ha, reg, 8, MSW(addr));
+
+ WRT_MAILBOX_REG(ha, reg, 2, MSW(dump_dma));
+ WRT_MAILBOX_REG(ha, reg, 3, LSW(dump_dma));
+ WRT_MAILBOX_REG(ha, reg, 6, MSW(MSD(dump_dma)));
+ WRT_MAILBOX_REG(ha, reg, 7, LSW(MSD(dump_dma)));
+
+ WRT_MAILBOX_REG(ha, reg, 4, words);
+ WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT);
+
+ for (timer = 6000000; timer; timer--) {
+ /* Check for pending interrupts. */
+ stat = RD_REG_DWORD(®->u.isp2300.host_status);
+ if (stat & HSR_RISC_INT) {
+ stat &= 0xff;
+
+ if (stat == 0x1 || stat == 0x2) {
+ set_bit(MBX_INTERRUPT,
+ &ha->mbx_cmd_flags);
+
+ mb0 = RD_MAILBOX_REG(ha, reg, 0);
+
+ /* Release mailbox registers. */
+ WRT_REG_WORD(®->semaphore, 0);
+ WRT_REG_WORD(®->hccr,
+ HCCR_CLR_RISC_INT);
+ RD_REG_WORD(®->hccr);
+ break;
+ } else if (stat == 0x10 || stat == 0x11) {
+ set_bit(MBX_INTERRUPT,
+ &ha->mbx_cmd_flags);
+
+ mb0 = RD_MAILBOX_REG(ha, reg, 0);
+
+ WRT_REG_WORD(®->hccr,
+ HCCR_CLR_RISC_INT);
+ RD_REG_WORD(®->hccr);
+ break;
+ }
+
+ /* clear this intr; it wasn't a mailbox intr */
+ WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT);
+ RD_REG_WORD(®->hccr);
+ }
+ udelay(5);
+ }
+
+ if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
+ rval = mb0 & MBS_MASK;
+ for (idx = 0; idx < words; idx++)
+ ram[cnt + idx] = swab16(dump[idx]);
+ } else {
+ rval = QLA_FUNCTION_FAILED;
+ }
+ }
+
+ *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL;
+ return rval;
+}
+
static inline void
qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count,
uint16_t *buf)
qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
{
int rval;
- uint32_t cnt, timer;
- uint32_t risc_address;
- uint16_t mb0, mb2;
+ uint32_t cnt;
- uint32_t stat;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
uint16_t __iomem *dmp_reg;
unsigned long flags;
struct qla2300_fw_dump *fw;
- uint32_t data_ram_cnt;
+ void *nxt;
- risc_address = data_ram_cnt = 0;
- mb0 = mb2 = 0;
flags = 0;
if (!hardware_locked)
}
}
- if (rval == QLA_SUCCESS) {
- /* Get RISC SRAM. */
- risc_address = 0x800;
- WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
- clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
- }
- for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;
- cnt++, risc_address++) {
- WRT_MAILBOX_REG(ha, reg, 1, (uint16_t)risc_address);
- WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT);
-
- for (timer = 6000000; timer; timer--) {
- /* Check for pending interrupts. */
- stat = RD_REG_DWORD(®->u.isp2300.host_status);
- if (stat & HSR_RISC_INT) {
- stat &= 0xff;
-
- if (stat == 0x1 || stat == 0x2) {
- set_bit(MBX_INTERRUPT,
- &ha->mbx_cmd_flags);
-
- mb0 = RD_MAILBOX_REG(ha, reg, 0);
- mb2 = RD_MAILBOX_REG(ha, reg, 2);
-
- /* Release mailbox registers. */
- WRT_REG_WORD(®->semaphore, 0);
- WRT_REG_WORD(®->hccr,
- HCCR_CLR_RISC_INT);
- RD_REG_WORD(®->hccr);
- break;
- } else if (stat == 0x10 || stat == 0x11) {
- set_bit(MBX_INTERRUPT,
- &ha->mbx_cmd_flags);
-
- mb0 = RD_MAILBOX_REG(ha, reg, 0);
- mb2 = RD_MAILBOX_REG(ha, reg, 2);
-
- WRT_REG_WORD(®->hccr,
- HCCR_CLR_RISC_INT);
- RD_REG_WORD(®->hccr);
- break;
- }
-
- /* clear this intr; it wasn't a mailbox intr */
- WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT);
- RD_REG_WORD(®->hccr);
- }
- udelay(5);
- }
-
- if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
- rval = mb0 & MBS_MASK;
- fw->risc_ram[cnt] = htons(mb2);
- } else {
- rval = QLA_FUNCTION_FAILED;
- }
- }
-
- if (rval == QLA_SUCCESS) {
- /* Get stack SRAM. */
- risc_address = 0x10000;
- WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED);
- clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
- }
- for (cnt = 0; cnt < sizeof(fw->stack_ram) / 2 && rval == QLA_SUCCESS;
- cnt++, risc_address++) {
- WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address));
- WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address));
- WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT);
-
- for (timer = 6000000; timer; timer--) {
- /* Check for pending interrupts. */
- stat = RD_REG_DWORD(®->u.isp2300.host_status);
- if (stat & HSR_RISC_INT) {
- stat &= 0xff;
-
- if (stat == 0x1 || stat == 0x2) {
- set_bit(MBX_INTERRUPT,
- &ha->mbx_cmd_flags);
-
- mb0 = RD_MAILBOX_REG(ha, reg, 0);
- mb2 = RD_MAILBOX_REG(ha, reg, 2);
-
- /* Release mailbox registers. */
- WRT_REG_WORD(®->semaphore, 0);
- WRT_REG_WORD(®->hccr,
- HCCR_CLR_RISC_INT);
- RD_REG_WORD(®->hccr);
- break;
- } else if (stat == 0x10 || stat == 0x11) {
- set_bit(MBX_INTERRUPT,
- &ha->mbx_cmd_flags);
-
- mb0 = RD_MAILBOX_REG(ha, reg, 0);
- mb2 = RD_MAILBOX_REG(ha, reg, 2);
-
- WRT_REG_WORD(®->hccr,
- HCCR_CLR_RISC_INT);
- RD_REG_WORD(®->hccr);
- break;
- }
-
- /* clear this intr; it wasn't a mailbox intr */
- WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT);
- RD_REG_WORD(®->hccr);
- }
- udelay(5);
- }
-
- if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
- rval = mb0 & MBS_MASK;
- fw->stack_ram[cnt] = htons(mb2);
- } else {
- rval = QLA_FUNCTION_FAILED;
- }
- }
-
- if (rval == QLA_SUCCESS) {
- /* Get data SRAM. */
- risc_address = 0x11000;
- data_ram_cnt = ha->fw_memory_size - risc_address + 1;
- WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED);
- clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
- }
- for (cnt = 0; cnt < data_ram_cnt && rval == QLA_SUCCESS;
- cnt++, risc_address++) {
- WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address));
- WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address));
- WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT);
-
- for (timer = 6000000; timer; timer--) {
- /* Check for pending interrupts. */
- stat = RD_REG_DWORD(®->u.isp2300.host_status);
- if (stat & HSR_RISC_INT) {
- stat &= 0xff;
-
- if (stat == 0x1 || stat == 0x2) {
- set_bit(MBX_INTERRUPT,
- &ha->mbx_cmd_flags);
-
- mb0 = RD_MAILBOX_REG(ha, reg, 0);
- mb2 = RD_MAILBOX_REG(ha, reg, 2);
-
- /* Release mailbox registers. */
- WRT_REG_WORD(®->semaphore, 0);
- WRT_REG_WORD(®->hccr,
- HCCR_CLR_RISC_INT);
- RD_REG_WORD(®->hccr);
- break;
- } else if (stat == 0x10 || stat == 0x11) {
- set_bit(MBX_INTERRUPT,
- &ha->mbx_cmd_flags);
-
- mb0 = RD_MAILBOX_REG(ha, reg, 0);
- mb2 = RD_MAILBOX_REG(ha, reg, 2);
-
- WRT_REG_WORD(®->hccr,
- HCCR_CLR_RISC_INT);
- RD_REG_WORD(®->hccr);
- break;
- }
+ /* Get RISC SRAM. */
+ if (rval == QLA_SUCCESS)
+ rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram,
+ sizeof(fw->risc_ram) / 2, &nxt);
- /* clear this intr; it wasn't a mailbox intr */
- WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT);
- RD_REG_WORD(®->hccr);
- }
- udelay(5);
- }
+ /* Get stack SRAM. */
+ if (rval == QLA_SUCCESS)
+ rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram,
+ sizeof(fw->stack_ram) / 2, &nxt);
- if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
- rval = mb0 & MBS_MASK;
- fw->data_ram[cnt] = htons(mb2);
- } else {
- rval = QLA_FUNCTION_FAILED;
- }
- }
+ /* Get data SRAM. */
+ if (rval == QLA_SUCCESS)
+ rval = qla2xxx_dump_ram(ha, 0x11000, fw->data_ram,
+ ha->fw_memory_size - 0x11000 + 1, &nxt);
if (rval == QLA_SUCCESS)
- qla2xxx_copy_queues(ha, &fw->data_ram[cnt]);
+ qla2xxx_copy_queues(ha, nxt);
if (rval != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha,
goto qla24xx_fw_dump_failed_0;
rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
- fw->ext_mem, &nxt);
+ &nxt);
if (rval != QLA_SUCCESS)
goto qla24xx_fw_dump_failed_0;
goto qla25xx_fw_dump_failed_0;
rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
- fw->ext_mem, &nxt);
+ &nxt);
if (rval != QLA_SUCCESS)
goto qla25xx_fw_dump_failed_0;