[SCSI] qla2xxx: Correct MQ-chain information retrieval during a firmware dump.
Original code would not read request/response queue pointers. Also, collapse code into a helper qla25xx_copy_mq() function in preparation for newer ISP parts. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
committed by
James Bottomley
parent
bb99de6703
commit
d63ab53394
@@ -347,6 +347,39 @@ qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
|
|||||||
return iter_reg;
|
return iter_reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
|
||||||
|
{
|
||||||
|
uint32_t cnt, que_idx;
|
||||||
|
uint8_t req_cnt, rsp_cnt, que_cnt;
|
||||||
|
struct qla2xxx_mq_chain *mq = ptr;
|
||||||
|
struct device_reg_25xxmq __iomem *reg;
|
||||||
|
|
||||||
|
if (!ha->mqenable)
|
||||||
|
return ptr;
|
||||||
|
|
||||||
|
mq = ptr;
|
||||||
|
*last_chain = &mq->type;
|
||||||
|
mq->type = __constant_htonl(DUMP_CHAIN_MQ);
|
||||||
|
mq->chain_size = __constant_htonl(sizeof(struct qla2xxx_mq_chain));
|
||||||
|
|
||||||
|
req_cnt = find_first_zero_bit(ha->req_qid_map, ha->max_queues);
|
||||||
|
rsp_cnt = find_first_zero_bit(ha->rsp_qid_map, ha->max_queues);
|
||||||
|
que_cnt = req_cnt > rsp_cnt ? req_cnt : rsp_cnt;
|
||||||
|
mq->count = htonl(que_cnt);
|
||||||
|
for (cnt = 0; cnt < que_cnt; cnt++) {
|
||||||
|
reg = (struct device_reg_25xxmq *) ((void *)
|
||||||
|
ha->mqiobase + cnt * QLA_QUE_PAGE);
|
||||||
|
que_idx = cnt * 4;
|
||||||
|
mq->qregs[que_idx] = htonl(RD_REG_DWORD(®->req_q_in));
|
||||||
|
mq->qregs[que_idx+1] = htonl(RD_REG_DWORD(®->req_q_out));
|
||||||
|
mq->qregs[que_idx+2] = htonl(RD_REG_DWORD(®->rsp_q_in));
|
||||||
|
mq->qregs[que_idx+3] = htonl(RD_REG_DWORD(®->rsp_q_out));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr + sizeof(struct qla2xxx_mq_chain);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
|
* qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
|
||||||
* @ha: HA context
|
* @ha: HA context
|
||||||
@@ -979,19 +1012,14 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
|||||||
uint32_t risc_address;
|
uint32_t risc_address;
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
||||||
struct device_reg_25xxmq __iomem *reg25;
|
|
||||||
uint32_t __iomem *dmp_reg;
|
uint32_t __iomem *dmp_reg;
|
||||||
uint32_t *iter_reg;
|
uint32_t *iter_reg;
|
||||||
uint16_t __iomem *mbx_reg;
|
uint16_t __iomem *mbx_reg;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct qla25xx_fw_dump *fw;
|
struct qla25xx_fw_dump *fw;
|
||||||
uint32_t ext_mem_cnt;
|
uint32_t ext_mem_cnt;
|
||||||
void *nxt;
|
void *nxt, *nxt_chain;
|
||||||
uint32_t *last_chain = NULL;
|
uint32_t *last_chain = NULL;
|
||||||
struct qla2xxx_mq_chain *mq = NULL;
|
|
||||||
uint32_t qreg_size;
|
|
||||||
uint8_t req_cnt, rsp_cnt, que_cnt;
|
|
||||||
uint32_t que_idx;
|
|
||||||
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
|
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
|
||||||
|
|
||||||
risc_address = ext_mem_cnt = 0;
|
risc_address = ext_mem_cnt = 0;
|
||||||
@@ -1038,29 +1066,6 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
|||||||
fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
|
fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
|
||||||
fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window));
|
fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window));
|
||||||
|
|
||||||
/* Multi queue registers */
|
|
||||||
if (ha->mqenable) {
|
|
||||||
qreg_size = sizeof(struct qla2xxx_mq_chain);
|
|
||||||
mq = kzalloc(qreg_size, GFP_KERNEL);
|
|
||||||
if (!mq)
|
|
||||||
goto qla25xx_fw_dump_failed_0;
|
|
||||||
req_cnt = find_first_zero_bit(ha->req_qid_map, ha->max_queues);
|
|
||||||
rsp_cnt = find_first_zero_bit(ha->rsp_qid_map, ha->max_queues);
|
|
||||||
que_cnt = req_cnt > rsp_cnt ? req_cnt : rsp_cnt;
|
|
||||||
mq->count = htonl(que_cnt);
|
|
||||||
mq->chain_size = htonl(qreg_size);
|
|
||||||
last_chain = &mq->type;
|
|
||||||
mq->type = __constant_htonl(DUMP_CHAIN_MQ);
|
|
||||||
for (cnt = 0; cnt < que_cnt; cnt++) {
|
|
||||||
reg25 = (struct device_reg_25xxmq *) ((void *)
|
|
||||||
ha->mqiobase + cnt * QLA_QUE_PAGE);
|
|
||||||
que_idx = cnt * 4;
|
|
||||||
mq->qregs[que_idx] = htonl(reg25->req_q_in);
|
|
||||||
mq->qregs[que_idx+1] = htonl(reg25->req_q_out);
|
|
||||||
mq->qregs[que_idx+2] = htonl(reg25->rsp_q_in);
|
|
||||||
mq->qregs[que_idx+3] = htonl(reg25->rsp_q_out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WRT_REG_DWORD(®->iobase_window, 0x00);
|
WRT_REG_DWORD(®->iobase_window, 0x00);
|
||||||
RD_REG_DWORD(®->iobase_window);
|
RD_REG_DWORD(®->iobase_window);
|
||||||
|
|
||||||
@@ -1278,6 +1283,10 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
|||||||
iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
|
iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
|
||||||
qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
|
qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
|
||||||
|
|
||||||
|
/* Multi queue registers */
|
||||||
|
nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
|
||||||
|
&last_chain);
|
||||||
|
|
||||||
rval = qla24xx_soft_reset(ha);
|
rval = qla24xx_soft_reset(ha);
|
||||||
if (rval != QLA_SUCCESS)
|
if (rval != QLA_SUCCESS)
|
||||||
goto qla25xx_fw_dump_failed_0;
|
goto qla25xx_fw_dump_failed_0;
|
||||||
@@ -1291,14 +1300,8 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
|||||||
|
|
||||||
nxt = qla24xx_copy_eft(ha, nxt);
|
nxt = qla24xx_copy_eft(ha, nxt);
|
||||||
|
|
||||||
/* Chain entries. */
|
/* Chain entries -- started with MQ. */
|
||||||
if (ha->mqenable) {
|
qla25xx_copy_fce(ha, nxt_chain, &last_chain);
|
||||||
memcpy(nxt, mq, qreg_size);
|
|
||||||
kfree(mq);
|
|
||||||
nxt += qreg_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
qla25xx_copy_fce(ha, nxt, &last_chain);
|
|
||||||
if (last_chain) {
|
if (last_chain) {
|
||||||
ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
|
ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
|
||||||
*last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
|
*last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
|
||||||
|
Reference in New Issue
Block a user