]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[SCSI] qla2xxx: Correct MQ-chain information retrieval during a firmware dump.
authorAndrew Vasquez <andrew.vasquez@qlogic.com>
Mon, 5 Jan 2009 19:18:09 +0000 (11:18 -0800)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Wed, 7 Jan 2009 21:50:59 +0000 (15:50 -0600)
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>
drivers/scsi/qla2xxx/qla_dbg.c

index 49040ed3cea8b47aa4ace2e8ed3822616db45590..4f478364fa435f7ab68c0761a47831c39ab626f5 100644 (file)
@@ -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(&reg->req_q_in));
+               mq->qregs[que_idx+1] = htonl(RD_REG_DWORD(&reg->req_q_out));
+               mq->qregs[que_idx+2] = htonl(RD_REG_DWORD(&reg->rsp_q_in));
+               mq->qregs[que_idx+3] = htonl(RD_REG_DWORD(&reg->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(&reg->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(&reg->iobase_window, 0x00);
        RD_REG_DWORD(&reg->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);