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 | |
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')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_inline.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 68 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 22 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 176 |
8 files changed, 174 insertions, 115 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 5ecf29283b6..a29c9520497 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -181,11 +181,14 @@ | |||
181 | #define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/ | 181 | #define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/ |
182 | #define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/ | 182 | #define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/ |
183 | 183 | ||
184 | struct req_que; | ||
185 | |||
184 | /* | 186 | /* |
185 | * SCSI Request Block | 187 | * SCSI Request Block |
186 | */ | 188 | */ |
187 | typedef struct srb { | 189 | typedef struct srb { |
188 | struct scsi_qla_host *vha; /* HA the SP is queued on */ | 190 | struct scsi_qla_host *vha; /* HA the SP is queued on */ |
191 | struct req_que *que; | ||
189 | struct fc_port *fcport; | 192 | struct fc_port *fcport; |
190 | 193 | ||
191 | struct scsi_cmnd *cmd; /* Linux SCSI command pkt */ | 194 | struct scsi_cmnd *cmd; /* Linux SCSI command pkt */ |
@@ -2045,7 +2048,6 @@ typedef struct vport_params { | |||
2045 | #define VP_RET_CODE_NOT_FOUND 6 | 2048 | #define VP_RET_CODE_NOT_FOUND 6 |
2046 | 2049 | ||
2047 | struct qla_hw_data; | 2050 | struct qla_hw_data; |
2048 | struct req_que; | ||
2049 | 2051 | ||
2050 | /* | 2052 | /* |
2051 | * ISP operations | 2053 | * ISP operations |
@@ -2101,6 +2103,9 @@ struct isp_operations { | |||
2101 | 2103 | ||
2102 | int (*get_flash_version) (struct scsi_qla_host *, void *); | 2104 | int (*get_flash_version) (struct scsi_qla_host *, void *); |
2103 | int (*start_scsi) (srb_t *); | 2105 | int (*start_scsi) (srb_t *); |
2106 | void (*wrt_req_reg) (struct qla_hw_data *, uint16_t, uint16_t); | ||
2107 | void (*wrt_rsp_reg) (struct qla_hw_data *, uint16_t, uint16_t); | ||
2108 | uint16_t (*rd_req_reg) (struct qla_hw_data *, uint16_t); | ||
2104 | }; | 2109 | }; |
2105 | 2110 | ||
2106 | /* MSI-X Support *************************************************************/ | 2111 | /* MSI-X Support *************************************************************/ |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index d9712b54349..0011e31205d 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -391,4 +391,10 @@ extern int qla25xx_delete_req_que(struct scsi_qla_host *, struct req_que *); | |||
391 | extern int qla25xx_delete_rsp_que(struct scsi_qla_host *, struct rsp_que *); | 391 | extern int qla25xx_delete_rsp_que(struct scsi_qla_host *, struct rsp_que *); |
392 | extern int qla25xx_create_queues(struct scsi_qla_host *, uint8_t); | 392 | extern int qla25xx_create_queues(struct scsi_qla_host *, uint8_t); |
393 | extern int qla25xx_delete_queues(struct scsi_qla_host *, uint8_t); | 393 | extern int qla25xx_delete_queues(struct scsi_qla_host *, uint8_t); |
394 | extern uint16_t qla24xx_rd_req_reg(struct qla_hw_data *, uint16_t); | ||
395 | extern uint16_t qla25xx_rd_req_reg(struct qla_hw_data *, uint16_t); | ||
396 | extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); | ||
397 | extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); | ||
398 | extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); | ||
399 | extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); | ||
394 | #endif /* _QLA_GBL_H */ | 400 | #endif /* _QLA_GBL_H */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b1495ec0bf3..52ed56ecf19 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -796,7 +796,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
796 | if (!tc) { | 796 | if (!tc) { |
797 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | 797 | qla_printk(KERN_WARNING, ha, "Unable to allocate " |
798 | "(%d KB) for FCE.\n", FCE_SIZE / 1024); | 798 | "(%d KB) for FCE.\n", FCE_SIZE / 1024); |
799 | goto cont_alloc; | 799 | goto try_eft; |
800 | } | 800 | } |
801 | 801 | ||
802 | memset(tc, 0, FCE_SIZE); | 802 | memset(tc, 0, FCE_SIZE); |
@@ -808,7 +808,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
808 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, | 808 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, |
809 | tc_dma); | 809 | tc_dma); |
810 | ha->flags.fce_enabled = 0; | 810 | ha->flags.fce_enabled = 0; |
811 | goto cont_alloc; | 811 | goto try_eft; |
812 | } | 812 | } |
813 | 813 | ||
814 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n", | 814 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n", |
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 507a6e954f5..5e0a7095c9f 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
@@ -63,4 +63,4 @@ qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id) | |||
63 | 63 | ||
64 | return ((loop_id > ha->max_loop_id && loop_id < SNS_FIRST_LOOP_ID) || | 64 | return ((loop_id > ha->max_loop_id && loop_id < SNS_FIRST_LOOP_ID) || |
65 | loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST); | 65 | loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST); |
66 | }; | 66 | } |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 6d2bd97c3b1..5bedc9d0594 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 | |||
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index eb4b43d7697..d5fb79a8800 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1446,7 +1446,6 @@ void | |||
1446 | qla24xx_process_response_queue(struct rsp_que *rsp) | 1446 | qla24xx_process_response_queue(struct rsp_que *rsp) |
1447 | { | 1447 | { |
1448 | struct qla_hw_data *ha = rsp->hw; | 1448 | struct qla_hw_data *ha = rsp->hw; |
1449 | device_reg_t __iomem *reg = ISP_QUE_REG(ha, rsp->id); | ||
1450 | struct sts_entry_24xx *pkt; | 1449 | struct sts_entry_24xx *pkt; |
1451 | struct scsi_qla_host *vha; | 1450 | struct scsi_qla_host *vha; |
1452 | 1451 | ||
@@ -1500,10 +1499,7 @@ qla24xx_process_response_queue(struct rsp_que *rsp) | |||
1500 | } | 1499 | } |
1501 | 1500 | ||
1502 | /* Adjust ring index */ | 1501 | /* Adjust ring index */ |
1503 | if (ha->mqenable) | 1502 | ha->isp_ops->wrt_rsp_reg(ha, rsp->id, rsp->ring_index); |
1504 | WRT_REG_DWORD(®->isp25mq.rsp_q_out, rsp->ring_index); | ||
1505 | else | ||
1506 | WRT_REG_DWORD(®->isp24.rsp_q_out, rsp->ring_index); | ||
1507 | } | 1503 | } |
1508 | 1504 | ||
1509 | static void | 1505 | static void |
@@ -1702,7 +1698,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) | |||
1702 | if (!rsp->id) | 1698 | if (!rsp->id) |
1703 | msix_disabled_hccr &= __constant_cpu_to_le32(BIT_22); | 1699 | msix_disabled_hccr &= __constant_cpu_to_le32(BIT_22); |
1704 | else | 1700 | else |
1705 | msix_disabled_hccr &= BIT_6; | 1701 | msix_disabled_hccr &= __constant_cpu_to_le32(BIT_6); |
1706 | 1702 | ||
1707 | qla24xx_process_response_queue(rsp); | 1703 | qla24xx_process_response_queue(rsp); |
1708 | 1704 | ||
@@ -2077,3 +2073,17 @@ int qla25xx_request_irq(struct rsp_que *rsp) | |||
2077 | return ret; | 2073 | return ret; |
2078 | } | 2074 | } |
2079 | 2075 | ||
2076 | void | ||
2077 | qla25xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index) | ||
2078 | { | ||
2079 | device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id; | ||
2080 | WRT_REG_DWORD(®->isp25mq.rsp_q_out, index); | ||
2081 | } | ||
2082 | |||
2083 | void | ||
2084 | qla24xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index) | ||
2085 | { | ||
2086 | device_reg_t __iomem *reg = (void *) ha->iobase; | ||
2087 | WRT_REG_DWORD(®->isp24.rsp_q_out, index); | ||
2088 | } | ||
2089 | |||
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index c54bc977c7b..a99976f5fab 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -3129,7 +3129,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req, | |||
3129 | } | 3129 | } |
3130 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 3130 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
3131 | 3131 | ||
3132 | rval = (int)qla2x00_mailbox_command(vha, mcp); | 3132 | rval = qla2x00_mailbox_command(vha, mcp); |
3133 | if (rval != QLA_SUCCESS) | 3133 | if (rval != QLA_SUCCESS) |
3134 | DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x mb0=%x.\n", | 3134 | DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x mb0=%x.\n", |
3135 | __func__, vha->host_no, rval, mcp->mb[0])); | 3135 | __func__, vha->host_no, rval, mcp->mb[0])); |
@@ -3180,7 +3180,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp, | |||
3180 | 3180 | ||
3181 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 3181 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
3182 | 3182 | ||
3183 | rval = (int)qla2x00_mailbox_command(vha, mcp); | 3183 | rval = qla2x00_mailbox_command(vha, mcp); |
3184 | if (rval != QLA_SUCCESS) | 3184 | if (rval != QLA_SUCCESS) |
3185 | DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x " | 3185 | DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x " |
3186 | "mb0=%x.\n", __func__, | 3186 | "mb0=%x.\n", __func__, |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 9142025db3d..8ea927788b3 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -441,6 +441,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport, | |||
441 | sp->vha = vha; | 441 | sp->vha = vha; |
442 | sp->fcport = fcport; | 442 | sp->fcport = fcport; |
443 | sp->cmd = cmd; | 443 | sp->cmd = cmd; |
444 | sp->que = ha->req_q_map[0]; | ||
444 | sp->flags = 0; | 445 | sp->flags = 0; |
445 | CMD_SP(cmd) = (void *)sp; | 446 | CMD_SP(cmd) = (void *)sp; |
446 | cmd->scsi_done = done; | 447 | cmd->scsi_done = done; |
@@ -775,13 +776,14 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
775 | { | 776 | { |
776 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 777 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
777 | srb_t *sp; | 778 | srb_t *sp; |
778 | int ret, i, que; | 779 | int ret, i; |
779 | unsigned int id, lun; | 780 | unsigned int id, lun; |
780 | unsigned long serial; | 781 | unsigned long serial; |
781 | unsigned long flags; | 782 | unsigned long flags; |
782 | int wait = 0; | 783 | int wait = 0; |
783 | struct qla_hw_data *ha = vha->hw; | 784 | struct qla_hw_data *ha = vha->hw; |
784 | struct req_que *req; | 785 | struct req_que *req; |
786 | srb_t *spt; | ||
785 | 787 | ||
786 | qla2x00_block_error_handler(cmd); | 788 | qla2x00_block_error_handler(cmd); |
787 | 789 | ||
@@ -793,37 +795,36 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
793 | id = cmd->device->id; | 795 | id = cmd->device->id; |
794 | lun = cmd->device->lun; | 796 | lun = cmd->device->lun; |
795 | serial = cmd->serial_number; | 797 | serial = cmd->serial_number; |
798 | spt = (srb_t *) CMD_SP(cmd); | ||
799 | if (!spt) | ||
800 | return SUCCESS; | ||
801 | req = spt->que; | ||
796 | 802 | ||
797 | /* Check active list for command command. */ | 803 | /* Check active list for command command. */ |
798 | spin_lock_irqsave(&ha->hardware_lock, flags); | 804 | spin_lock_irqsave(&ha->hardware_lock, flags); |
799 | for (que = 0; que < QLA_MAX_HOST_QUES; que++) { | 805 | for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { |
800 | req = ha->req_q_map[vha->req_ques[que]]; | 806 | sp = req->outstanding_cmds[i]; |
801 | if (!req) | ||
802 | continue; | ||
803 | for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { | ||
804 | sp = req->outstanding_cmds[i]; | ||
805 | 807 | ||
806 | if (sp == NULL) | 808 | if (sp == NULL) |
807 | continue; | 809 | continue; |
808 | 810 | ||
809 | if (sp->cmd != cmd) | 811 | if (sp->cmd != cmd) |
810 | continue; | 812 | continue; |
811 | 813 | ||
812 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC." | 814 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC." |
813 | " pid=%ld.\n", __func__, vha->host_no, sp, serial)); | 815 | " pid=%ld.\n", __func__, vha->host_no, sp, serial)); |
814 | 816 | ||
815 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 817 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
816 | if (ha->isp_ops->abort_command(vha, sp, req)) { | 818 | if (ha->isp_ops->abort_command(vha, sp, req)) { |
817 | DEBUG2(printk("%s(%ld): abort_command " | 819 | DEBUG2(printk("%s(%ld): abort_command " |
818 | "mbx failed.\n", __func__, vha->host_no)); | 820 | "mbx failed.\n", __func__, vha->host_no)); |
819 | } else { | 821 | } else { |
820 | DEBUG3(printk("%s(%ld): abort_command " | 822 | DEBUG3(printk("%s(%ld): abort_command " |
821 | "mbx success.\n", __func__, vha->host_no)); | 823 | "mbx success.\n", __func__, vha->host_no)); |
822 | wait = 1; | 824 | wait = 1; |
823 | } | ||
824 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
825 | break; | ||
826 | } | 825 | } |
826 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
827 | break; | ||
827 | } | 828 | } |
828 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 829 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
829 | 830 | ||
@@ -852,48 +853,46 @@ enum nexus_wait_type { | |||
852 | 853 | ||
853 | static int | 854 | static int |
854 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, | 855 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, |
855 | unsigned int l, enum nexus_wait_type type) | 856 | unsigned int l, srb_t *sp, enum nexus_wait_type type) |
856 | { | 857 | { |
857 | int cnt, match, status, que; | 858 | int cnt, match, status; |
858 | srb_t *sp; | ||
859 | unsigned long flags; | 859 | unsigned long flags; |
860 | struct qla_hw_data *ha = vha->hw; | 860 | struct qla_hw_data *ha = vha->hw; |
861 | struct req_que *req; | 861 | struct req_que *req; |
862 | 862 | ||
863 | status = QLA_SUCCESS; | 863 | status = QLA_SUCCESS; |
864 | if (!sp) | ||
865 | return status; | ||
866 | |||
864 | spin_lock_irqsave(&ha->hardware_lock, flags); | 867 | spin_lock_irqsave(&ha->hardware_lock, flags); |
865 | for (que = 0; que < QLA_MAX_HOST_QUES; que++) { | 868 | req = sp->que; |
866 | req = ha->req_q_map[vha->req_ques[que]]; | 869 | for (cnt = 1; status == QLA_SUCCESS && |
867 | if (!req) | 870 | cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { |
871 | sp = req->outstanding_cmds[cnt]; | ||
872 | if (!sp) | ||
868 | continue; | 873 | continue; |
869 | for (cnt = 1; status == QLA_SUCCESS && | ||
870 | cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
871 | sp = req->outstanding_cmds[cnt]; | ||
872 | if (!sp) | ||
873 | continue; | ||
874 | |||
875 | if (vha->vp_idx != sp->fcport->vha->vp_idx) | ||
876 | continue; | ||
877 | match = 0; | ||
878 | switch (type) { | ||
879 | case WAIT_HOST: | ||
880 | match = 1; | ||
881 | break; | ||
882 | case WAIT_TARGET: | ||
883 | match = sp->cmd->device->id == t; | ||
884 | break; | ||
885 | case WAIT_LUN: | ||
886 | match = (sp->cmd->device->id == t && | ||
887 | sp->cmd->device->lun == l); | ||
888 | break; | ||
889 | } | ||
890 | if (!match) | ||
891 | continue; | ||
892 | 874 | ||
893 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 875 | if (vha->vp_idx != sp->fcport->vha->vp_idx) |
894 | status = qla2x00_eh_wait_on_command(sp->cmd); | 876 | continue; |
895 | spin_lock_irqsave(&ha->hardware_lock, flags); | 877 | match = 0; |
878 | switch (type) { | ||
879 | case WAIT_HOST: | ||
880 | match = 1; | ||
881 | break; | ||
882 | case WAIT_TARGET: | ||
883 | match = sp->cmd->device->id == t; | ||
884 | break; | ||
885 | case WAIT_LUN: | ||
886 | match = (sp->cmd->device->id == t && | ||
887 | sp->cmd->device->lun == l); | ||
888 | break; | ||
896 | } | 889 | } |
890 | if (!match) | ||
891 | continue; | ||
892 | |||
893 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
894 | status = qla2x00_eh_wait_on_command(sp->cmd); | ||
895 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
897 | } | 896 | } |
898 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 897 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
899 | 898 | ||
@@ -934,7 +933,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, | |||
934 | goto eh_reset_failed; | 933 | goto eh_reset_failed; |
935 | err = 3; | 934 | err = 3; |
936 | if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id, | 935 | if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id, |
937 | cmd->device->lun, type) != QLA_SUCCESS) | 936 | cmd->device->lun, (srb_t *) CMD_SP(cmd), type) != QLA_SUCCESS) |
938 | goto eh_reset_failed; | 937 | goto eh_reset_failed; |
939 | 938 | ||
940 | qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n", | 939 | qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n", |
@@ -992,6 +991,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | |||
992 | int ret = FAILED; | 991 | int ret = FAILED; |
993 | unsigned int id, lun; | 992 | unsigned int id, lun; |
994 | unsigned long serial; | 993 | unsigned long serial; |
994 | srb_t *sp = (srb_t *) CMD_SP(cmd); | ||
995 | 995 | ||
996 | qla2x00_block_error_handler(cmd); | 996 | qla2x00_block_error_handler(cmd); |
997 | 997 | ||
@@ -1018,7 +1018,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | |||
1018 | goto eh_bus_reset_done; | 1018 | goto eh_bus_reset_done; |
1019 | 1019 | ||
1020 | /* Flush outstanding commands. */ | 1020 | /* Flush outstanding commands. */ |
1021 | if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) != | 1021 | if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, sp, WAIT_HOST) != |
1022 | QLA_SUCCESS) | 1022 | QLA_SUCCESS) |
1023 | ret = FAILED; | 1023 | ret = FAILED; |
1024 | 1024 | ||
@@ -1053,6 +1053,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1053 | int ret = FAILED; | 1053 | int ret = FAILED; |
1054 | unsigned int id, lun; | 1054 | unsigned int id, lun; |
1055 | unsigned long serial; | 1055 | unsigned long serial; |
1056 | srb_t *sp = (srb_t *) CMD_SP(cmd); | ||
1056 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | 1057 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); |
1057 | 1058 | ||
1058 | qla2x00_block_error_handler(cmd); | 1059 | qla2x00_block_error_handler(cmd); |
@@ -1096,7 +1097,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1096 | } | 1097 | } |
1097 | 1098 | ||
1098 | /* Waiting for command to be returned to OS.*/ | 1099 | /* Waiting for command to be returned to OS.*/ |
1099 | if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) == | 1100 | if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, sp, WAIT_HOST) == |
1100 | QLA_SUCCESS) | 1101 | QLA_SUCCESS) |
1101 | ret = SUCCESS; | 1102 | ret = SUCCESS; |
1102 | 1103 | ||
@@ -1368,6 +1369,9 @@ static struct isp_operations qla2100_isp_ops = { | |||
1368 | .write_optrom = qla2x00_write_optrom_data, | 1369 | .write_optrom = qla2x00_write_optrom_data, |
1369 | .get_flash_version = qla2x00_get_flash_version, | 1370 | .get_flash_version = qla2x00_get_flash_version, |
1370 | .start_scsi = qla2x00_start_scsi, | 1371 | .start_scsi = qla2x00_start_scsi, |
1372 | .wrt_req_reg = NULL, | ||
1373 | .wrt_rsp_reg = NULL, | ||
1374 | .rd_req_reg = NULL, | ||
1371 | }; | 1375 | }; |
1372 | 1376 | ||
1373 | static struct isp_operations qla2300_isp_ops = { | 1377 | static struct isp_operations qla2300_isp_ops = { |
@@ -1403,6 +1407,9 @@ static struct isp_operations qla2300_isp_ops = { | |||
1403 | .write_optrom = qla2x00_write_optrom_data, | 1407 | .write_optrom = qla2x00_write_optrom_data, |
1404 | .get_flash_version = qla2x00_get_flash_version, | 1408 | .get_flash_version = qla2x00_get_flash_version, |
1405 | .start_scsi = qla2x00_start_scsi, | 1409 | .start_scsi = qla2x00_start_scsi, |
1410 | .wrt_req_reg = NULL, | ||
1411 | .wrt_rsp_reg = NULL, | ||
1412 | .rd_req_reg = NULL, | ||
1406 | }; | 1413 | }; |
1407 | 1414 | ||
1408 | static struct isp_operations qla24xx_isp_ops = { | 1415 | static struct isp_operations qla24xx_isp_ops = { |
@@ -1438,6 +1445,9 @@ static struct isp_operations qla24xx_isp_ops = { | |||
1438 | .write_optrom = qla24xx_write_optrom_data, | 1445 | .write_optrom = qla24xx_write_optrom_data, |
1439 | .get_flash_version = qla24xx_get_flash_version, | 1446 | .get_flash_version = qla24xx_get_flash_version, |
1440 | .start_scsi = qla24xx_start_scsi, | 1447 | .start_scsi = qla24xx_start_scsi, |
1448 | .wrt_req_reg = qla24xx_wrt_req_reg, | ||
1449 | .wrt_rsp_reg = qla24xx_wrt_rsp_reg, | ||
1450 | .rd_req_reg = qla24xx_rd_req_reg, | ||
1441 | }; | 1451 | }; |
1442 | 1452 | ||
1443 | static struct isp_operations qla25xx_isp_ops = { | 1453 | static struct isp_operations qla25xx_isp_ops = { |
@@ -1473,6 +1483,9 @@ static struct isp_operations qla25xx_isp_ops = { | |||
1473 | .write_optrom = qla24xx_write_optrom_data, | 1483 | .write_optrom = qla24xx_write_optrom_data, |
1474 | .get_flash_version = qla24xx_get_flash_version, | 1484 | .get_flash_version = qla24xx_get_flash_version, |
1475 | .start_scsi = qla24xx_start_scsi, | 1485 | .start_scsi = qla24xx_start_scsi, |
1486 | .wrt_req_reg = qla24xx_wrt_req_reg, | ||
1487 | .wrt_rsp_reg = qla24xx_wrt_rsp_reg, | ||
1488 | .rd_req_reg = qla24xx_rd_req_reg, | ||
1476 | }; | 1489 | }; |
1477 | 1490 | ||
1478 | static inline void | 1491 | static inline void |
@@ -1616,26 +1629,27 @@ skip_pio: | |||
1616 | 1629 | ||
1617 | /* Determine queue resources */ | 1630 | /* Determine queue resources */ |
1618 | ha->max_queues = 1; | 1631 | ha->max_queues = 1; |
1619 | if (ql2xmaxqueues > 1) { | 1632 | if (ql2xmaxqueues <= 1 || !IS_QLA25XX(ha)) |
1620 | ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3), | 1633 | goto mqiobase_exit; |
1621 | pci_resource_len(ha->pdev, 3)); | 1634 | ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3), |
1622 | if (ha->mqiobase) { | 1635 | pci_resource_len(ha->pdev, 3)); |
1623 | /* Read MSIX vector size of the board */ | 1636 | if (ha->mqiobase) { |
1624 | pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, | 1637 | /* Read MSIX vector size of the board */ |
1625 | &msix); | 1638 | pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix); |
1626 | ha->msix_count = msix; | 1639 | ha->msix_count = msix; |
1627 | /* Max queues are bounded by available msix vectors */ | 1640 | /* Max queues are bounded by available msix vectors */ |
1628 | /* queue 0 uses two msix vectors */ | 1641 | /* queue 0 uses two msix vectors */ |
1629 | if (ha->msix_count - 1 < ql2xmaxqueues) | 1642 | if (ha->msix_count - 1 < ql2xmaxqueues) |
1630 | ha->max_queues = ha->msix_count - 1; | 1643 | ha->max_queues = ha->msix_count - 1; |
1631 | else if (ql2xmaxqueues > QLA_MQ_SIZE) | 1644 | else if (ql2xmaxqueues > QLA_MQ_SIZE) |
1632 | ha->max_queues = QLA_MQ_SIZE; | 1645 | ha->max_queues = QLA_MQ_SIZE; |
1633 | else | 1646 | else |
1634 | ha->max_queues = ql2xmaxqueues; | 1647 | ha->max_queues = ql2xmaxqueues; |
1635 | qla_printk(KERN_INFO, ha, | 1648 | qla_printk(KERN_INFO, ha, |
1636 | "MSI-X vector count: %d\n", msix); | 1649 | "MSI-X vector count: %d\n", msix); |
1637 | } | ||
1638 | } | 1650 | } |
1651 | |||
1652 | mqiobase_exit: | ||
1639 | ha->msix_count = ha->max_queues + 1; | 1653 | ha->msix_count = ha->max_queues + 1; |
1640 | return (0); | 1654 | return (0); |
1641 | 1655 | ||
@@ -1852,6 +1866,12 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1852 | ha->rsp_q_map[0] = rsp; | 1866 | ha->rsp_q_map[0] = rsp; |
1853 | ha->req_q_map[0] = req; | 1867 | ha->req_q_map[0] = req; |
1854 | 1868 | ||
1869 | if (ha->mqenable) { | ||
1870 | ha->isp_ops->wrt_req_reg = qla25xx_wrt_req_reg; | ||
1871 | ha->isp_ops->wrt_rsp_reg = qla25xx_wrt_rsp_reg; | ||
1872 | ha->isp_ops->rd_req_reg = qla25xx_rd_req_reg; | ||
1873 | } | ||
1874 | |||
1855 | if (qla2x00_initialize_adapter(base_vha)) { | 1875 | if (qla2x00_initialize_adapter(base_vha)) { |
1856 | qla_printk(KERN_WARNING, ha, | 1876 | qla_printk(KERN_WARNING, ha, |
1857 | "Failed to initialize adapter\n"); | 1877 | "Failed to initialize adapter\n"); |