diff options
author | Anirban Chakraborty <anirban.chakraborty@qlogic.com> | 2008-12-18 13:06:15 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-12-29 12:24:35 -0500 |
commit | 17d98630a4f2a38537618503ad0c7ec97ba461ca (patch) | |
tree | 27deaa971e7b3a95a56a0ba5cf4c92e12853a775 /drivers/scsi/qla2xxx/qla_iocb.c | |
parent | 20c09df7eb9c92a40e0ecf654b6e8f14c8583b9e (diff) |
[SCSI] qla2xxx: changes in multiq code
Following changes have been made:
1. Scan outstanding commands only in the queue where it is submitted
2. Update queue registers directly in the fast path
3. Queue specific BAR is remapped only for multiq capable adapters
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_iocb.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 6d2bd97c3b11..5bedc9d05942 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -160,7 +160,6 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
160 | struct scatterlist *sg; | 160 | struct scatterlist *sg; |
161 | int i; | 161 | int i; |
162 | struct req_que *req; | 162 | struct req_que *req; |
163 | uint16_t que_id; | ||
164 | 163 | ||
165 | cmd = sp->cmd; | 164 | cmd = sp->cmd; |
166 | 165 | ||
@@ -175,8 +174,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
175 | } | 174 | } |
176 | 175 | ||
177 | vha = sp->vha; | 176 | vha = sp->vha; |
178 | que_id = vha->req_ques[0]; | 177 | req = sp->que; |
179 | req = vha->hw->req_q_map[que_id]; | ||
180 | 178 | ||
181 | cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp)); | 179 | cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp)); |
182 | 180 | ||
@@ -223,7 +221,6 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
223 | struct scatterlist *sg; | 221 | struct scatterlist *sg; |
224 | int i; | 222 | int i; |
225 | struct req_que *req; | 223 | struct req_que *req; |
226 | uint16_t que_id; | ||
227 | 224 | ||
228 | cmd = sp->cmd; | 225 | cmd = sp->cmd; |
229 | 226 | ||
@@ -238,8 +235,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
238 | } | 235 | } |
239 | 236 | ||
240 | vha = sp->vha; | 237 | vha = sp->vha; |
241 | que_id = vha->req_ques[0]; | 238 | req = sp->que; |
242 | req = vha->hw->req_q_map[que_id]; | ||
243 | 239 | ||
244 | cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp)); | 240 | cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp)); |
245 | 241 | ||
@@ -358,6 +354,7 @@ qla2x00_start_scsi(srb_t *sp) | |||
358 | req->current_outstanding_cmd = handle; | 354 | req->current_outstanding_cmd = handle; |
359 | req->outstanding_cmds[handle] = sp; | 355 | req->outstanding_cmds[handle] = sp; |
360 | sp->vha = vha; | 356 | sp->vha = vha; |
357 | sp->que = req; | ||
361 | sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; | 358 | sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; |
362 | req->cnt -= req_cnt; | 359 | req->cnt -= req_cnt; |
363 | 360 | ||
@@ -573,6 +570,7 @@ qla2x00_isp_cmd(struct scsi_qla_host *vha, struct req_que *req) | |||
573 | { | 570 | { |
574 | struct qla_hw_data *ha = vha->hw; | 571 | struct qla_hw_data *ha = vha->hw; |
575 | device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id); | 572 | device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id); |
573 | struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp; | ||
576 | 574 | ||
577 | DEBUG5(printk("%s(): IOCB data:\n", __func__)); | 575 | DEBUG5(printk("%s(): IOCB data:\n", __func__)); |
578 | DEBUG5(qla2x00_dump_buffer( | 576 | DEBUG5(qla2x00_dump_buffer( |
@@ -587,8 +585,10 @@ qla2x00_isp_cmd(struct scsi_qla_host *vha, struct req_que *req) | |||
587 | req->ring_ptr++; | 585 | req->ring_ptr++; |
588 | 586 | ||
589 | /* Set chip new ring index. */ | 587 | /* Set chip new ring index. */ |
590 | if (ha->mqenable) | 588 | if (ha->mqenable) { |
591 | RD_REG_DWORD(®->isp25mq.req_q_out); | 589 | WRT_REG_DWORD(®->isp25mq.req_q_in, req->ring_index); |
590 | RD_REG_DWORD(&ioreg->hccr); | ||
591 | } | ||
592 | else { | 592 | else { |
593 | if (IS_FWI2_CAPABLE(ha)) { | 593 | if (IS_FWI2_CAPABLE(ha)) { |
594 | WRT_REG_DWORD(®->isp24.req_q_in, req->ring_index); | 594 | WRT_REG_DWORD(®->isp24.req_q_in, req->ring_index); |
@@ -642,7 +642,6 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, | |||
642 | struct scsi_cmnd *cmd; | 642 | struct scsi_cmnd *cmd; |
643 | struct scatterlist *sg; | 643 | struct scatterlist *sg; |
644 | int i; | 644 | int i; |
645 | uint16_t que_id; | ||
646 | struct req_que *req; | 645 | struct req_que *req; |
647 | 646 | ||
648 | cmd = sp->cmd; | 647 | cmd = sp->cmd; |
@@ -658,8 +657,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, | |||
658 | } | 657 | } |
659 | 658 | ||
660 | vha = sp->vha; | 659 | vha = sp->vha; |
661 | que_id = vha->req_ques[0]; | 660 | req = sp->que; |
662 | req = vha->hw->req_q_map[que_id]; | ||
663 | 661 | ||
664 | /* Set transfer direction */ | 662 | /* Set transfer direction */ |
665 | if (cmd->sc_data_direction == DMA_TO_DEVICE) { | 663 | if (cmd->sc_data_direction == DMA_TO_DEVICE) { |
@@ -727,7 +725,6 @@ qla24xx_start_scsi(srb_t *sp) | |||
727 | struct scsi_cmnd *cmd = sp->cmd; | 725 | struct scsi_cmnd *cmd = sp->cmd; |
728 | struct scsi_qla_host *vha = sp->vha; | 726 | struct scsi_qla_host *vha = sp->vha; |
729 | struct qla_hw_data *ha = vha->hw; | 727 | struct qla_hw_data *ha = vha->hw; |
730 | device_reg_t __iomem *reg; | ||
731 | uint16_t que_id; | 728 | uint16_t que_id; |
732 | 729 | ||
733 | /* Setup device pointers. */ | 730 | /* Setup device pointers. */ |
@@ -735,7 +732,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
735 | que_id = vha->req_ques[0]; | 732 | que_id = vha->req_ques[0]; |
736 | 733 | ||
737 | req = ha->req_q_map[que_id]; | 734 | req = ha->req_q_map[que_id]; |
738 | reg = ISP_QUE_REG(ha, req->id); | 735 | sp->que = req; |
739 | 736 | ||
740 | if (req->rsp) | 737 | if (req->rsp) |
741 | rsp = req->rsp; | 738 | rsp = req->rsp; |
@@ -780,12 +777,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
780 | 777 | ||
781 | req_cnt = qla24xx_calc_iocbs(tot_dsds); | 778 | req_cnt = qla24xx_calc_iocbs(tot_dsds); |
782 | if (req->cnt < (req_cnt + 2)) { | 779 | if (req->cnt < (req_cnt + 2)) { |
783 | if (ha->mqenable) | 780 | cnt = ha->isp_ops->rd_req_reg(ha, req->id); |
784 | cnt = (uint16_t) | ||
785 | RD_REG_DWORD_RELAXED(®->isp25mq.req_q_out); | ||
786 | else | ||
787 | cnt = (uint16_t) | ||
788 | RD_REG_DWORD_RELAXED(®->isp24.req_q_out); | ||
789 | 781 | ||
790 | if (req->ring_index < cnt) | 782 | if (req->ring_index < cnt) |
791 | req->cnt = cnt - req->ring_index; | 783 | req->cnt = cnt - req->ring_index; |
@@ -846,12 +838,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
846 | sp->flags |= SRB_DMA_VALID; | 838 | sp->flags |= SRB_DMA_VALID; |
847 | 839 | ||
848 | /* Set chip new ring index. */ | 840 | /* Set chip new ring index. */ |
849 | if (ha->mqenable) | 841 | ha->isp_ops->wrt_req_reg(ha, req->id, req->ring_index); |
850 | WRT_REG_DWORD(®->isp25mq.req_q_in, req->ring_index); | ||
851 | else { | ||
852 | WRT_REG_DWORD(®->isp24.req_q_in, req->ring_index); | ||
853 | RD_REG_DWORD_RELAXED(®->isp24.req_q_in); | ||
854 | } | ||
855 | 842 | ||
856 | /* Manage unprocessed RIO/ZIO commands in response queue. */ | 843 | /* Manage unprocessed RIO/ZIO commands in response queue. */ |
857 | if (vha->flags.process_response_queue && | 844 | if (vha->flags.process_response_queue && |
@@ -870,3 +857,34 @@ queuing_error: | |||
870 | return QLA_FUNCTION_FAILED; | 857 | return QLA_FUNCTION_FAILED; |
871 | } | 858 | } |
872 | 859 | ||
860 | uint16_t | ||
861 | qla24xx_rd_req_reg(struct qla_hw_data *ha, uint16_t id) | ||
862 | { | ||
863 | device_reg_t __iomem *reg = (void *) ha->iobase; | ||
864 | return RD_REG_DWORD_RELAXED(®->isp24.req_q_out); | ||
865 | } | ||
866 | |||
867 | uint16_t | ||
868 | qla25xx_rd_req_reg(struct qla_hw_data *ha, uint16_t id) | ||
869 | { | ||
870 | device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id; | ||
871 | return RD_REG_DWORD_RELAXED(®->isp25mq.req_q_out); | ||
872 | } | ||
873 | |||
874 | void | ||
875 | qla24xx_wrt_req_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index) | ||
876 | { | ||
877 | device_reg_t __iomem *reg = (void *) ha->iobase; | ||
878 | WRT_REG_DWORD(®->isp24.req_q_in, index); | ||
879 | RD_REG_DWORD_RELAXED(®->isp24.req_q_in); | ||
880 | } | ||
881 | |||
882 | void | ||
883 | qla25xx_wrt_req_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index) | ||
884 | { | ||
885 | device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id; | ||
886 | struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp; | ||
887 | WRT_REG_DWORD(®->isp25mq.req_q_in, index); | ||
888 | RD_REG_DWORD(&ioreg->hccr); /* PCI posting */ | ||
889 | } | ||
890 | |||