[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:
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;
|
||||
}
|
||||
|
||||
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.
|
||||
* @ha: HA context
|
||||
|
@ -979,19 +1012,14 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
|||
uint32_t risc_address;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
||||
struct device_reg_25xxmq __iomem *reg25;
|
||||
uint32_t __iomem *dmp_reg;
|
||||
uint32_t *iter_reg;
|
||||
uint16_t __iomem *mbx_reg;
|
||||
unsigned long flags;
|
||||
struct qla25xx_fw_dump *fw;
|
||||
uint32_t ext_mem_cnt;
|
||||
void *nxt;
|
||||
void *nxt, *nxt_chain;
|
||||
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);
|
||||
|
||||
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[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);
|
||||
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);
|
||||
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);
|
||||
if (rval != QLA_SUCCESS)
|
||||
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);
|
||||
|
||||
/* Chain entries. */
|
||||
if (ha->mqenable) {
|
||||
memcpy(nxt, mq, qreg_size);
|
||||
kfree(mq);
|
||||
nxt += qreg_size;
|
||||
}
|
||||
|
||||
qla25xx_copy_fce(ha, nxt, &last_chain);
|
||||
/* Chain entries -- started with MQ. */
|
||||
qla25xx_copy_fce(ha, nxt_chain, &last_chain);
|
||||
if (last_chain) {
|
||||
ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
|
||||
*last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
|
||||
|
|
Loading…
Reference in a new issue