aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2009-01-05 14:18:09 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-01-07 16:50:59 -0500
commitd63ab53394f408f9e59f5b6ba0580f8c6ef2357a (patch)
tree7a1d17ecdfa754ed0819c3104a09a148c078599b /drivers/scsi/qla2xxx
parentbb99de6703526ebed42e29b8dee402df235f28c7 (diff)
[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>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c77
1 files changed, 40 insertions, 37 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 49040ed3cea8..4f478364fa43 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -347,6 +347,39 @@ qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
347 return iter_reg; 347 return iter_reg;
348} 348}
349 349
350static inline void *
351qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
352{
353 uint32_t cnt, que_idx;
354 uint8_t req_cnt, rsp_cnt, que_cnt;
355 struct qla2xxx_mq_chain *mq = ptr;
356 struct device_reg_25xxmq __iomem *reg;
357
358 if (!ha->mqenable)
359 return ptr;
360
361 mq = ptr;
362 *last_chain = &mq->type;
363 mq->type = __constant_htonl(DUMP_CHAIN_MQ);
364 mq->chain_size = __constant_htonl(sizeof(struct qla2xxx_mq_chain));
365
366 req_cnt = find_first_zero_bit(ha->req_qid_map, ha->max_queues);
367 rsp_cnt = find_first_zero_bit(ha->rsp_qid_map, ha->max_queues);
368 que_cnt = req_cnt > rsp_cnt ? req_cnt : rsp_cnt;
369 mq->count = htonl(que_cnt);
370 for (cnt = 0; cnt < que_cnt; cnt++) {
371 reg = (struct device_reg_25xxmq *) ((void *)
372 ha->mqiobase + cnt * QLA_QUE_PAGE);
373 que_idx = cnt * 4;
374 mq->qregs[que_idx] = htonl(RD_REG_DWORD(&reg->req_q_in));
375 mq->qregs[que_idx+1] = htonl(RD_REG_DWORD(&reg->req_q_out));
376 mq->qregs[que_idx+2] = htonl(RD_REG_DWORD(&reg->rsp_q_in));
377 mq->qregs[que_idx+3] = htonl(RD_REG_DWORD(&reg->rsp_q_out));
378 }
379
380 return ptr + sizeof(struct qla2xxx_mq_chain);
381}
382
350/** 383/**
351 * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. 384 * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
352 * @ha: HA context 385 * @ha: HA context
@@ -979,19 +1012,14 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
979 uint32_t risc_address; 1012 uint32_t risc_address;
980 struct qla_hw_data *ha = vha->hw; 1013 struct qla_hw_data *ha = vha->hw;
981 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 1014 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
982 struct device_reg_25xxmq __iomem *reg25;
983 uint32_t __iomem *dmp_reg; 1015 uint32_t __iomem *dmp_reg;
984 uint32_t *iter_reg; 1016 uint32_t *iter_reg;
985 uint16_t __iomem *mbx_reg; 1017 uint16_t __iomem *mbx_reg;
986 unsigned long flags; 1018 unsigned long flags;
987 struct qla25xx_fw_dump *fw; 1019 struct qla25xx_fw_dump *fw;
988 uint32_t ext_mem_cnt; 1020 uint32_t ext_mem_cnt;
989 void *nxt; 1021 void *nxt, *nxt_chain;
990 uint32_t *last_chain = NULL; 1022 uint32_t *last_chain = NULL;
991 struct qla2xxx_mq_chain *mq = NULL;
992 uint32_t qreg_size;
993 uint8_t req_cnt, rsp_cnt, que_cnt;
994 uint32_t que_idx;
995 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 1023 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
996 1024
997 risc_address = ext_mem_cnt = 0; 1025 risc_address = ext_mem_cnt = 0;
@@ -1038,29 +1066,6 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
1038 fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg)); 1066 fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
1039 fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window)); 1067 fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
1040 1068
1041 /* Multi queue registers */
1042 if (ha->mqenable) {
1043 qreg_size = sizeof(struct qla2xxx_mq_chain);
1044 mq = kzalloc(qreg_size, GFP_KERNEL);
1045 if (!mq)
1046 goto qla25xx_fw_dump_failed_0;
1047 req_cnt = find_first_zero_bit(ha->req_qid_map, ha->max_queues);
1048 rsp_cnt = find_first_zero_bit(ha->rsp_qid_map, ha->max_queues);
1049 que_cnt = req_cnt > rsp_cnt ? req_cnt : rsp_cnt;
1050 mq->count = htonl(que_cnt);
1051 mq->chain_size = htonl(qreg_size);
1052 last_chain = &mq->type;
1053 mq->type = __constant_htonl(DUMP_CHAIN_MQ);
1054 for (cnt = 0; cnt < que_cnt; cnt++) {
1055 reg25 = (struct device_reg_25xxmq *) ((void *)
1056 ha->mqiobase + cnt * QLA_QUE_PAGE);
1057 que_idx = cnt * 4;
1058 mq->qregs[que_idx] = htonl(reg25->req_q_in);
1059 mq->qregs[que_idx+1] = htonl(reg25->req_q_out);
1060 mq->qregs[que_idx+2] = htonl(reg25->rsp_q_in);
1061 mq->qregs[que_idx+3] = htonl(reg25->rsp_q_out);
1062 }
1063 }
1064 WRT_REG_DWORD(&reg->iobase_window, 0x00); 1069 WRT_REG_DWORD(&reg->iobase_window, 0x00);
1065 RD_REG_DWORD(&reg->iobase_window); 1070 RD_REG_DWORD(&reg->iobase_window);
1066 1071
@@ -1278,6 +1283,10 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
1278 iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); 1283 iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
1279 qla24xx_read_window(reg, 0x6F00, 16, iter_reg); 1284 qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
1280 1285
1286 /* Multi queue registers */
1287 nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
1288 &last_chain);
1289
1281 rval = qla24xx_soft_reset(ha); 1290 rval = qla24xx_soft_reset(ha);
1282 if (rval != QLA_SUCCESS) 1291 if (rval != QLA_SUCCESS)
1283 goto qla25xx_fw_dump_failed_0; 1292 goto qla25xx_fw_dump_failed_0;
@@ -1291,14 +1300,8 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
1291 1300
1292 nxt = qla24xx_copy_eft(ha, nxt); 1301 nxt = qla24xx_copy_eft(ha, nxt);
1293 1302
1294 /* Chain entries. */ 1303 /* Chain entries -- started with MQ. */
1295 if (ha->mqenable) { 1304 qla25xx_copy_fce(ha, nxt_chain, &last_chain);
1296 memcpy(nxt, mq, qreg_size);
1297 kfree(mq);
1298 nxt += qreg_size;
1299 }
1300
1301 qla25xx_copy_fce(ha, nxt, &last_chain);
1302 if (last_chain) { 1305 if (last_chain) {
1303 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); 1306 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
1304 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); 1307 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST);