diff options
author | Anirban Chakraborty <anirban.chakraborty@qlogic.com> | 2008-12-09 19:45:39 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-12-29 12:24:33 -0500 |
commit | 73208dfd7ab19f379d73e8a0fbf30f92c203e5e8 (patch) | |
tree | f69be5e89817d17b066ece4dbe04e395339c0754 /drivers/scsi/qla2xxx/qla_init.c | |
parent | 85b4aa4926a50210b683ac89326e338e7d131211 (diff) |
[SCSI] qla2xxx: add support for multi-queue adapter
Following changes have been made.
1. qla_hw_data structure holds an array for request queue pointers,
and an array for response queue pointers.
2. The base request and response queues are created by default.
3. Additional request and response queues are created at the time of vport
creation. If queue resources are exhausted during vport creation, newly
created vports use the default queue.
4. Requests are sent to the request queue that the vport was assigned
in the beginning.
5. Responses are completed on the response queue with which the request queue
is associated with.
[fixup memcpy argument reversal spotted by davej@redhat.com]
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_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 192 |
1 files changed, 142 insertions, 50 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 7bee87f90f6d..b1495ec0bf35 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | #include "qla_gbl.h" | ||
8 | 9 | ||
9 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
10 | #include <linux/vmalloc.h> | 11 | #include <linux/vmalloc.h> |
@@ -21,7 +22,6 @@ | |||
21 | static int qla2x00_isp_firmware(scsi_qla_host_t *); | 22 | static int qla2x00_isp_firmware(scsi_qla_host_t *); |
22 | static void qla2x00_resize_request_q(scsi_qla_host_t *); | 23 | static void qla2x00_resize_request_q(scsi_qla_host_t *); |
23 | static int qla2x00_setup_chip(scsi_qla_host_t *); | 24 | static int qla2x00_setup_chip(scsi_qla_host_t *); |
24 | static void qla2x00_init_response_q_entries(scsi_qla_host_t *); | ||
25 | static int qla2x00_init_rings(scsi_qla_host_t *); | 25 | static int qla2x00_init_rings(scsi_qla_host_t *); |
26 | static int qla2x00_fw_ready(scsi_qla_host_t *); | 26 | static int qla2x00_fw_ready(scsi_qla_host_t *); |
27 | static int qla2x00_configure_hba(scsi_qla_host_t *); | 27 | static int qla2x00_configure_hba(scsi_qla_host_t *); |
@@ -39,6 +39,7 @@ static int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *); | |||
39 | 39 | ||
40 | static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *); | 40 | static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *); |
41 | static int qla84xx_init_chip(scsi_qla_host_t *); | 41 | static int qla84xx_init_chip(scsi_qla_host_t *); |
42 | static int qla25xx_init_queues(struct qla_hw_data *); | ||
42 | 43 | ||
43 | /****************************************************************************/ | 44 | /****************************************************************************/ |
44 | /* QLogic ISP2x00 Hardware Support Functions. */ | 45 | /* QLogic ISP2x00 Hardware Support Functions. */ |
@@ -59,6 +60,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) | |||
59 | { | 60 | { |
60 | int rval; | 61 | int rval; |
61 | struct qla_hw_data *ha = vha->hw; | 62 | struct qla_hw_data *ha = vha->hw; |
63 | struct req_que *req = ha->req_q_map[0]; | ||
62 | /* Clear adapter flags. */ | 64 | /* Clear adapter flags. */ |
63 | vha->flags.online = 0; | 65 | vha->flags.online = 0; |
64 | vha->flags.reset_active = 0; | 66 | vha->flags.reset_active = 0; |
@@ -73,6 +75,9 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) | |||
73 | ha->beacon_blink_led = 0; | 75 | ha->beacon_blink_led = 0; |
74 | set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); | 76 | set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); |
75 | 77 | ||
78 | set_bit(0, ha->req_qid_map); | ||
79 | set_bit(0, ha->rsp_qid_map); | ||
80 | |||
76 | qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); | 81 | qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); |
77 | rval = ha->isp_ops->pci_config(vha); | 82 | rval = ha->isp_ops->pci_config(vha); |
78 | if (rval) { | 83 | if (rval) { |
@@ -90,7 +95,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) | |||
90 | return (rval); | 95 | return (rval); |
91 | } | 96 | } |
92 | 97 | ||
93 | ha->isp_ops->get_flash_version(vha, ha->req->ring); | 98 | ha->isp_ops->get_flash_version(vha, req->ring); |
94 | 99 | ||
95 | qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); | 100 | qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); |
96 | 101 | ||
@@ -603,6 +608,7 @@ qla2x00_chip_diag(scsi_qla_host_t *vha) | |||
603 | uint16_t data; | 608 | uint16_t data; |
604 | uint32_t cnt; | 609 | uint32_t cnt; |
605 | uint16_t mb[5]; | 610 | uint16_t mb[5]; |
611 | struct req_que *req = ha->req_q_map[0]; | ||
606 | 612 | ||
607 | /* Assume a failed state */ | 613 | /* Assume a failed state */ |
608 | rval = QLA_FUNCTION_FAILED; | 614 | rval = QLA_FUNCTION_FAILED; |
@@ -671,11 +677,11 @@ qla2x00_chip_diag(scsi_qla_host_t *vha) | |||
671 | ha->product_id[3] = mb[4]; | 677 | ha->product_id[3] = mb[4]; |
672 | 678 | ||
673 | /* Adjust fw RISC transfer size */ | 679 | /* Adjust fw RISC transfer size */ |
674 | if (ha->req->length > 1024) | 680 | if (req->length > 1024) |
675 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024; | 681 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024; |
676 | else | 682 | else |
677 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * | 683 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * |
678 | ha->req->length; | 684 | req->length; |
679 | 685 | ||
680 | if (IS_QLA2200(ha) && | 686 | if (IS_QLA2200(ha) && |
681 | RD_MAILBOX_REG(ha, reg, 7) == QLA2200A_RISC_ROM_VER) { | 687 | RD_MAILBOX_REG(ha, reg, 7) == QLA2200A_RISC_ROM_VER) { |
@@ -725,11 +731,12 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) | |||
725 | { | 731 | { |
726 | int rval; | 732 | int rval; |
727 | struct qla_hw_data *ha = vha->hw; | 733 | struct qla_hw_data *ha = vha->hw; |
734 | struct req_que *req = ha->req_q_map[0]; | ||
728 | 735 | ||
729 | /* Perform RISC reset. */ | 736 | /* Perform RISC reset. */ |
730 | qla24xx_reset_risc(vha); | 737 | qla24xx_reset_risc(vha); |
731 | 738 | ||
732 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * ha->req->length; | 739 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length; |
733 | 740 | ||
734 | rval = qla2x00_mbx_reg_test(vha); | 741 | rval = qla2x00_mbx_reg_test(vha); |
735 | if (rval) { | 742 | if (rval) { |
@@ -750,10 +757,12 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
750 | { | 757 | { |
751 | int rval; | 758 | int rval; |
752 | uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, | 759 | uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, |
753 | eft_size, fce_size; | 760 | eft_size, fce_size, mq_size; |
754 | dma_addr_t tc_dma; | 761 | dma_addr_t tc_dma; |
755 | void *tc; | 762 | void *tc; |
756 | struct qla_hw_data *ha = vha->hw; | 763 | struct qla_hw_data *ha = vha->hw; |
764 | struct req_que *req = ha->req_q_map[0]; | ||
765 | struct rsp_que *rsp = ha->rsp_q_map[0]; | ||
757 | 766 | ||
758 | if (ha->fw_dump) { | 767 | if (ha->fw_dump) { |
759 | qla_printk(KERN_WARNING, ha, | 768 | qla_printk(KERN_WARNING, ha, |
@@ -762,7 +771,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
762 | } | 771 | } |
763 | 772 | ||
764 | ha->fw_dumped = 0; | 773 | ha->fw_dumped = 0; |
765 | fixed_size = mem_size = eft_size = fce_size = 0; | 774 | fixed_size = mem_size = eft_size = fce_size = mq_size = 0; |
766 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 775 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
767 | fixed_size = sizeof(struct qla2100_fw_dump); | 776 | fixed_size = sizeof(struct qla2100_fw_dump); |
768 | } else if (IS_QLA23XX(ha)) { | 777 | } else if (IS_QLA23XX(ha)) { |
@@ -771,10 +780,12 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
771 | sizeof(uint16_t); | 780 | sizeof(uint16_t); |
772 | } else if (IS_FWI2_CAPABLE(ha)) { | 781 | } else if (IS_FWI2_CAPABLE(ha)) { |
773 | fixed_size = IS_QLA25XX(ha) ? | 782 | fixed_size = IS_QLA25XX(ha) ? |
774 | offsetof(struct qla25xx_fw_dump, ext_mem): | 783 | offsetof(struct qla25xx_fw_dump, ext_mem) : |
775 | offsetof(struct qla24xx_fw_dump, ext_mem); | 784 | offsetof(struct qla24xx_fw_dump, ext_mem); |
776 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | 785 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * |
777 | sizeof(uint32_t); | 786 | sizeof(uint32_t); |
787 | if (ha->mqenable) | ||
788 | mq_size = sizeof(struct qla2xxx_mq_chain); | ||
778 | 789 | ||
779 | /* Allocate memory for Fibre Channel Event Buffer. */ | 790 | /* Allocate memory for Fibre Channel Event Buffer. */ |
780 | if (!IS_QLA25XX(ha)) | 791 | if (!IS_QLA25XX(ha)) |
@@ -785,7 +796,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
785 | if (!tc) { | 796 | if (!tc) { |
786 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | 797 | qla_printk(KERN_WARNING, ha, "Unable to allocate " |
787 | "(%d KB) for FCE.\n", FCE_SIZE / 1024); | 798 | "(%d KB) for FCE.\n", FCE_SIZE / 1024); |
788 | goto try_eft; | 799 | goto cont_alloc; |
789 | } | 800 | } |
790 | 801 | ||
791 | memset(tc, 0, FCE_SIZE); | 802 | memset(tc, 0, FCE_SIZE); |
@@ -797,7 +808,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
797 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, | 808 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, |
798 | tc_dma); | 809 | tc_dma); |
799 | ha->flags.fce_enabled = 0; | 810 | ha->flags.fce_enabled = 0; |
800 | goto try_eft; | 811 | goto cont_alloc; |
801 | } | 812 | } |
802 | 813 | ||
803 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n", | 814 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n", |
@@ -835,12 +846,12 @@ try_eft: | |||
835 | ha->eft = tc; | 846 | ha->eft = tc; |
836 | } | 847 | } |
837 | cont_alloc: | 848 | cont_alloc: |
838 | req_q_size = ha->req->length * sizeof(request_t); | 849 | req_q_size = req->length * sizeof(request_t); |
839 | rsp_q_size = ha->rsp->length * sizeof(response_t); | 850 | rsp_q_size = rsp->length * sizeof(response_t); |
840 | 851 | ||
841 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); | 852 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); |
842 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + | 853 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + |
843 | eft_size + fce_size; | 854 | mq_size + eft_size + fce_size; |
844 | 855 | ||
845 | ha->fw_dump = vmalloc(dump_size); | 856 | ha->fw_dump = vmalloc(dump_size); |
846 | if (!ha->fw_dump) { | 857 | if (!ha->fw_dump) { |
@@ -855,7 +866,6 @@ cont_alloc: | |||
855 | } | 866 | } |
856 | return; | 867 | return; |
857 | } | 868 | } |
858 | |||
859 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware dump...\n", | 869 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware dump...\n", |
860 | dump_size / 1024); | 870 | dump_size / 1024); |
861 | 871 | ||
@@ -894,7 +904,7 @@ qla2x00_resize_request_q(scsi_qla_host_t *vha) | |||
894 | dma_addr_t request_dma; | 904 | dma_addr_t request_dma; |
895 | request_t *request_ring; | 905 | request_t *request_ring; |
896 | struct qla_hw_data *ha = vha->hw; | 906 | struct qla_hw_data *ha = vha->hw; |
897 | struct req_que *req = ha->req; | 907 | struct req_que *req = ha->req_q_map[0]; |
898 | 908 | ||
899 | /* Valid only on recent ISPs. */ | 909 | /* Valid only on recent ISPs. */ |
900 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 910 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) |
@@ -1030,12 +1040,11 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) | |||
1030 | * | 1040 | * |
1031 | * Returns 0 on success. | 1041 | * Returns 0 on success. |
1032 | */ | 1042 | */ |
1033 | static void | 1043 | void |
1034 | qla2x00_init_response_q_entries(scsi_qla_host_t *vha) | 1044 | qla2x00_init_response_q_entries(struct rsp_que *rsp) |
1035 | { | 1045 | { |
1036 | uint16_t cnt; | 1046 | uint16_t cnt; |
1037 | response_t *pkt; | 1047 | response_t *pkt; |
1038 | struct rsp_que *rsp = vha->hw->rsp; | ||
1039 | 1048 | ||
1040 | pkt = rsp->ring_ptr; | 1049 | pkt = rsp->ring_ptr; |
1041 | for (cnt = 0; cnt < rsp->length; cnt++) { | 1050 | for (cnt = 0; cnt < rsp->length; cnt++) { |
@@ -1151,8 +1160,8 @@ qla2x00_config_rings(struct scsi_qla_host *vha) | |||
1151 | { | 1160 | { |
1152 | struct qla_hw_data *ha = vha->hw; | 1161 | struct qla_hw_data *ha = vha->hw; |
1153 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 1162 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
1154 | struct req_que *req = ha->req; | 1163 | struct req_que *req = ha->req_q_map[0]; |
1155 | struct rsp_que *rsp = ha->rsp; | 1164 | struct rsp_que *rsp = ha->rsp_q_map[0]; |
1156 | 1165 | ||
1157 | /* Setup ring parameters in initialization control block. */ | 1166 | /* Setup ring parameters in initialization control block. */ |
1158 | ha->init_cb->request_q_outpointer = __constant_cpu_to_le16(0); | 1167 | ha->init_cb->request_q_outpointer = __constant_cpu_to_le16(0); |
@@ -1175,12 +1184,15 @@ void | |||
1175 | qla24xx_config_rings(struct scsi_qla_host *vha) | 1184 | qla24xx_config_rings(struct scsi_qla_host *vha) |
1176 | { | 1185 | { |
1177 | struct qla_hw_data *ha = vha->hw; | 1186 | struct qla_hw_data *ha = vha->hw; |
1178 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1187 | device_reg_t __iomem *reg = ISP_QUE_REG(ha, 0); |
1188 | struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp; | ||
1189 | struct qla_msix_entry *msix; | ||
1179 | struct init_cb_24xx *icb; | 1190 | struct init_cb_24xx *icb; |
1180 | struct req_que *req = ha->req; | 1191 | uint16_t rid = 0; |
1181 | struct rsp_que *rsp = ha->rsp; | 1192 | struct req_que *req = ha->req_q_map[0]; |
1193 | struct rsp_que *rsp = ha->rsp_q_map[0]; | ||
1182 | 1194 | ||
1183 | /* Setup ring parameters in initialization control block. */ | 1195 | /* Setup ring parameters in initialization control block. */ |
1184 | icb = (struct init_cb_24xx *)ha->init_cb; | 1196 | icb = (struct init_cb_24xx *)ha->init_cb; |
1185 | icb->request_q_outpointer = __constant_cpu_to_le16(0); | 1197 | icb->request_q_outpointer = __constant_cpu_to_le16(0); |
1186 | icb->response_q_inpointer = __constant_cpu_to_le16(0); | 1198 | icb->response_q_inpointer = __constant_cpu_to_le16(0); |
@@ -1191,11 +1203,40 @@ qla24xx_config_rings(struct scsi_qla_host *vha) | |||
1191 | icb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma)); | 1203 | icb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma)); |
1192 | icb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma)); | 1204 | icb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma)); |
1193 | 1205 | ||
1194 | WRT_REG_DWORD(®->req_q_in, 0); | 1206 | if (ha->mqenable) { |
1195 | WRT_REG_DWORD(®->req_q_out, 0); | 1207 | icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS); |
1196 | WRT_REG_DWORD(®->rsp_q_in, 0); | 1208 | icb->rid = __constant_cpu_to_le16(rid); |
1197 | WRT_REG_DWORD(®->rsp_q_out, 0); | 1209 | if (ha->flags.msix_enabled) { |
1198 | RD_REG_DWORD(®->rsp_q_out); | 1210 | msix = &ha->msix_entries[1]; |
1211 | DEBUG2_17(printk(KERN_INFO | ||
1212 | "Reistering vector 0x%x for base que\n", msix->entry)); | ||
1213 | icb->msix = cpu_to_le16(msix->entry); | ||
1214 | } | ||
1215 | /* Use alternate PCI bus number */ | ||
1216 | if (MSB(rid)) | ||
1217 | icb->firmware_options_2 |= | ||
1218 | __constant_cpu_to_le32(BIT_19); | ||
1219 | /* Use alternate PCI devfn */ | ||
1220 | if (LSB(rid)) | ||
1221 | icb->firmware_options_2 |= | ||
1222 | __constant_cpu_to_le32(BIT_18); | ||
1223 | |||
1224 | icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_22); | ||
1225 | icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23); | ||
1226 | ha->rsp_q_map[0]->options = icb->firmware_options_2; | ||
1227 | |||
1228 | WRT_REG_DWORD(®->isp25mq.req_q_in, 0); | ||
1229 | WRT_REG_DWORD(®->isp25mq.req_q_out, 0); | ||
1230 | WRT_REG_DWORD(®->isp25mq.rsp_q_in, 0); | ||
1231 | WRT_REG_DWORD(®->isp25mq.rsp_q_out, 0); | ||
1232 | } else { | ||
1233 | WRT_REG_DWORD(®->isp24.req_q_in, 0); | ||
1234 | WRT_REG_DWORD(®->isp24.req_q_out, 0); | ||
1235 | WRT_REG_DWORD(®->isp24.rsp_q_in, 0); | ||
1236 | WRT_REG_DWORD(®->isp24.rsp_q_out, 0); | ||
1237 | } | ||
1238 | /* PCI posting */ | ||
1239 | RD_REG_DWORD(&ioreg->hccr); | ||
1199 | } | 1240 | } |
1200 | 1241 | ||
1201 | /** | 1242 | /** |
@@ -1214,8 +1255,8 @@ qla2x00_init_rings(scsi_qla_host_t *vha) | |||
1214 | unsigned long flags = 0; | 1255 | unsigned long flags = 0; |
1215 | int cnt; | 1256 | int cnt; |
1216 | struct qla_hw_data *ha = vha->hw; | 1257 | struct qla_hw_data *ha = vha->hw; |
1217 | struct req_que *req = ha->req; | 1258 | struct req_que *req = ha->req_q_map[0]; |
1218 | struct rsp_que *rsp = ha->rsp; | 1259 | struct rsp_que *rsp = ha->rsp_q_map[0]; |
1219 | struct mid_init_cb_24xx *mid_init_cb = | 1260 | struct mid_init_cb_24xx *mid_init_cb = |
1220 | (struct mid_init_cb_24xx *) ha->init_cb; | 1261 | (struct mid_init_cb_24xx *) ha->init_cb; |
1221 | 1262 | ||
@@ -1239,7 +1280,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha) | |||
1239 | rsp->ring_index = 0; | 1280 | rsp->ring_index = 0; |
1240 | 1281 | ||
1241 | /* Initialize response queue entries */ | 1282 | /* Initialize response queue entries */ |
1242 | qla2x00_init_response_q_entries(vha); | 1283 | qla2x00_init_response_q_entries(rsp); |
1243 | 1284 | ||
1244 | ha->isp_ops->config_rings(vha); | 1285 | ha->isp_ops->config_rings(vha); |
1245 | 1286 | ||
@@ -2039,10 +2080,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) | |||
2039 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) { | 2080 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) { |
2040 | if (test_bit(LOCAL_LOOP_UPDATE, &save_flags)) | 2081 | if (test_bit(LOCAL_LOOP_UPDATE, &save_flags)) |
2041 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | 2082 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); |
2042 | if (test_bit(RSCN_UPDATE, &save_flags)) { | 2083 | if (test_bit(RSCN_UPDATE, &save_flags)) |
2043 | set_bit(RSCN_UPDATE, &vha->dpc_flags); | 2084 | set_bit(RSCN_UPDATE, &vha->dpc_flags); |
2044 | vha->flags.rscn_queue_overflow = 1; | ||
2045 | } | ||
2046 | } | 2085 | } |
2047 | 2086 | ||
2048 | return (rval); | 2087 | return (rval); |
@@ -3169,10 +3208,11 @@ qla2x00_local_device_login(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
3169 | int | 3208 | int |
3170 | qla2x00_loop_resync(scsi_qla_host_t *vha) | 3209 | qla2x00_loop_resync(scsi_qla_host_t *vha) |
3171 | { | 3210 | { |
3172 | int rval; | 3211 | int rval = QLA_SUCCESS; |
3173 | uint32_t wait_time; | 3212 | uint32_t wait_time; |
3174 | 3213 | struct qla_hw_data *ha = vha->hw; | |
3175 | rval = QLA_SUCCESS; | 3214 | struct req_que *req = ha->req_q_map[0]; |
3215 | struct rsp_que *rsp = ha->rsp_q_map[0]; | ||
3176 | 3216 | ||
3177 | atomic_set(&vha->loop_state, LOOP_UPDATE); | 3217 | atomic_set(&vha->loop_state, LOOP_UPDATE); |
3178 | clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); | 3218 | clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); |
@@ -3184,7 +3224,8 @@ qla2x00_loop_resync(scsi_qla_host_t *vha) | |||
3184 | atomic_set(&vha->loop_state, LOOP_UPDATE); | 3224 | atomic_set(&vha->loop_state, LOOP_UPDATE); |
3185 | 3225 | ||
3186 | /* Issue a marker after FW becomes ready. */ | 3226 | /* Issue a marker after FW becomes ready. */ |
3187 | qla2x00_marker(vha, 0, 0, MK_SYNC_ALL); | 3227 | qla2x00_marker(vha, req, rsp, 0, 0, |
3228 | MK_SYNC_ALL); | ||
3188 | vha->marker_needed = 0; | 3229 | vha->marker_needed = 0; |
3189 | 3230 | ||
3190 | /* Remap devices on Loop. */ | 3231 | /* Remap devices on Loop. */ |
@@ -3237,6 +3278,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) | |||
3237 | uint8_t status = 0; | 3278 | uint8_t status = 0; |
3238 | struct qla_hw_data *ha = vha->hw; | 3279 | struct qla_hw_data *ha = vha->hw; |
3239 | struct scsi_qla_host *vp; | 3280 | struct scsi_qla_host *vp; |
3281 | struct req_que *req = ha->req_q_map[0]; | ||
3240 | 3282 | ||
3241 | if (vha->flags.online) { | 3283 | if (vha->flags.online) { |
3242 | vha->flags.online = 0; | 3284 | vha->flags.online = 0; |
@@ -3262,7 +3304,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) | |||
3262 | /* Requeue all commands in outstanding command list. */ | 3304 | /* Requeue all commands in outstanding command list. */ |
3263 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); | 3305 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); |
3264 | 3306 | ||
3265 | ha->isp_ops->get_flash_version(vha, ha->req->ring); | 3307 | ha->isp_ops->get_flash_version(vha, req->ring); |
3266 | 3308 | ||
3267 | ha->isp_ops->nvram_config(vha); | 3309 | ha->isp_ops->nvram_config(vha); |
3268 | 3310 | ||
@@ -3376,6 +3418,8 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) | |||
3376 | uint8_t status = 0; | 3418 | uint8_t status = 0; |
3377 | uint32_t wait_time; | 3419 | uint32_t wait_time; |
3378 | struct qla_hw_data *ha = vha->hw; | 3420 | struct qla_hw_data *ha = vha->hw; |
3421 | struct req_que *req = ha->req_q_map[0]; | ||
3422 | struct rsp_que *rsp = ha->rsp_q_map[0]; | ||
3379 | 3423 | ||
3380 | /* If firmware needs to be loaded */ | 3424 | /* If firmware needs to be loaded */ |
3381 | if (qla2x00_isp_firmware(vha)) { | 3425 | if (qla2x00_isp_firmware(vha)) { |
@@ -3387,13 +3431,16 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) | |||
3387 | 3431 | ||
3388 | if (!status && !(status = qla2x00_init_rings(vha))) { | 3432 | if (!status && !(status = qla2x00_init_rings(vha))) { |
3389 | clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); | 3433 | clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); |
3434 | /* Initialize the queues in use */ | ||
3435 | qla25xx_init_queues(ha); | ||
3436 | |||
3390 | status = qla2x00_fw_ready(vha); | 3437 | status = qla2x00_fw_ready(vha); |
3391 | if (!status) { | 3438 | if (!status) { |
3392 | DEBUG(printk("%s(): Start configure loop, " | 3439 | DEBUG(printk("%s(): Start configure loop, " |
3393 | "status = %d\n", __func__, status)); | 3440 | "status = %d\n", __func__, status)); |
3394 | 3441 | ||
3395 | /* Issue a marker after FW becomes ready. */ | 3442 | /* Issue a marker after FW becomes ready. */ |
3396 | qla2x00_marker(vha, 0, 0, MK_SYNC_ALL); | 3443 | qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); |
3397 | 3444 | ||
3398 | vha->flags.online = 1; | 3445 | vha->flags.online = 1; |
3399 | /* Wait at most MAX_TARGET RSCNs for a stable link. */ | 3446 | /* Wait at most MAX_TARGET RSCNs for a stable link. */ |
@@ -3419,6 +3466,46 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) | |||
3419 | return (status); | 3466 | return (status); |
3420 | } | 3467 | } |
3421 | 3468 | ||
3469 | static int | ||
3470 | qla25xx_init_queues(struct qla_hw_data *ha) | ||
3471 | { | ||
3472 | struct rsp_que *rsp = NULL; | ||
3473 | struct req_que *req = NULL; | ||
3474 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); | ||
3475 | int ret = -1; | ||
3476 | int i; | ||
3477 | |||
3478 | for (i = 1; i < ha->max_queues; i++) { | ||
3479 | rsp = ha->rsp_q_map[i]; | ||
3480 | if (rsp) { | ||
3481 | rsp->options &= ~BIT_0; | ||
3482 | ret = qla25xx_init_rsp_que(base_vha, rsp, rsp->options); | ||
3483 | if (ret != QLA_SUCCESS) | ||
3484 | DEBUG2_17(printk(KERN_WARNING | ||
3485 | "%s Rsp que:%d init failed\n", __func__, | ||
3486 | rsp->id)); | ||
3487 | else | ||
3488 | DEBUG2_17(printk(KERN_INFO | ||
3489 | "%s Rsp que:%d inited\n", __func__, | ||
3490 | rsp->id)); | ||
3491 | } | ||
3492 | req = ha->req_q_map[i]; | ||
3493 | if (req) { | ||
3494 | req->options &= ~BIT_0; | ||
3495 | ret = qla25xx_init_req_que(base_vha, req, req->options); | ||
3496 | if (ret != QLA_SUCCESS) | ||
3497 | DEBUG2_17(printk(KERN_WARNING | ||
3498 | "%s Req que:%d init failed\n", __func__, | ||
3499 | req->id)); | ||
3500 | else | ||
3501 | DEBUG2_17(printk(KERN_WARNING | ||
3502 | "%s Rsp que:%d inited\n", __func__, | ||
3503 | req->id)); | ||
3504 | } | ||
3505 | } | ||
3506 | return ret; | ||
3507 | } | ||
3508 | |||
3422 | /* | 3509 | /* |
3423 | * qla2x00_reset_adapter | 3510 | * qla2x00_reset_adapter |
3424 | * Reset adapter. | 3511 | * Reset adapter. |
@@ -3736,7 +3823,7 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
3736 | static int | 3823 | static int |
3737 | qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr) | 3824 | qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr) |
3738 | { | 3825 | { |
3739 | int rval; | 3826 | int rval = QLA_SUCCESS; |
3740 | int segments, fragment; | 3827 | int segments, fragment; |
3741 | uint32_t faddr; | 3828 | uint32_t faddr; |
3742 | uint32_t *dcode, dlen; | 3829 | uint32_t *dcode, dlen; |
@@ -3744,11 +3831,12 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
3744 | uint32_t risc_size; | 3831 | uint32_t risc_size; |
3745 | uint32_t i; | 3832 | uint32_t i; |
3746 | struct qla_hw_data *ha = vha->hw; | 3833 | struct qla_hw_data *ha = vha->hw; |
3834 | struct req_que *req = ha->req_q_map[0]; | ||
3747 | rval = QLA_SUCCESS; | 3835 | rval = QLA_SUCCESS; |
3748 | 3836 | ||
3749 | segments = FA_RISC_CODE_SEGMENTS; | 3837 | segments = FA_RISC_CODE_SEGMENTS; |
3750 | faddr = ha->flt_region_fw; | 3838 | faddr = ha->flt_region_fw; |
3751 | dcode = (uint32_t *)ha->req->ring; | 3839 | dcode = (uint32_t *)req->ring; |
3752 | *srisc_addr = 0; | 3840 | *srisc_addr = 0; |
3753 | 3841 | ||
3754 | /* Validate firmware image by checking version. */ | 3842 | /* Validate firmware image by checking version. */ |
@@ -3790,7 +3878,7 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
3790 | for (i = 0; i < dlen; i++) | 3878 | for (i = 0; i < dlen; i++) |
3791 | dcode[i] = swab32(dcode[i]); | 3879 | dcode[i] = swab32(dcode[i]); |
3792 | 3880 | ||
3793 | rval = qla2x00_load_ram(vha, ha->req->dma, risc_addr, | 3881 | rval = qla2x00_load_ram(vha, req->dma, risc_addr, |
3794 | dlen); | 3882 | dlen); |
3795 | if (rval) { | 3883 | if (rval) { |
3796 | DEBUG(printk("scsi(%ld):[ERROR] Failed to load " | 3884 | DEBUG(printk("scsi(%ld):[ERROR] Failed to load " |
@@ -3826,6 +3914,7 @@ qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
3826 | uint32_t risc_addr, risc_size, fwclen, wlen, *seg; | 3914 | uint32_t risc_addr, risc_size, fwclen, wlen, *seg; |
3827 | struct fw_blob *blob; | 3915 | struct fw_blob *blob; |
3828 | struct qla_hw_data *ha = vha->hw; | 3916 | struct qla_hw_data *ha = vha->hw; |
3917 | struct req_que *req = ha->req_q_map[0]; | ||
3829 | 3918 | ||
3830 | /* Load firmware blob. */ | 3919 | /* Load firmware blob. */ |
3831 | blob = qla2x00_request_firmware(vha); | 3920 | blob = qla2x00_request_firmware(vha); |
@@ -3838,7 +3927,7 @@ qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
3838 | 3927 | ||
3839 | rval = QLA_SUCCESS; | 3928 | rval = QLA_SUCCESS; |
3840 | 3929 | ||
3841 | wcode = (uint16_t *)ha->req->ring; | 3930 | wcode = (uint16_t *)req->ring; |
3842 | *srisc_addr = 0; | 3931 | *srisc_addr = 0; |
3843 | fwcode = (uint16_t *)blob->fw->data; | 3932 | fwcode = (uint16_t *)blob->fw->data; |
3844 | fwclen = 0; | 3933 | fwclen = 0; |
@@ -3891,7 +3980,7 @@ qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
3891 | for (i = 0; i < wlen; i++) | 3980 | for (i = 0; i < wlen; i++) |
3892 | wcode[i] = swab16(fwcode[i]); | 3981 | wcode[i] = swab16(fwcode[i]); |
3893 | 3982 | ||
3894 | rval = qla2x00_load_ram(vha, ha->req->dma, risc_addr, | 3983 | rval = qla2x00_load_ram(vha, req->dma, risc_addr, |
3895 | wlen); | 3984 | wlen); |
3896 | if (rval) { | 3985 | if (rval) { |
3897 | DEBUG(printk("scsi(%ld):[ERROR] Failed to load " | 3986 | DEBUG(printk("scsi(%ld):[ERROR] Failed to load " |
@@ -3930,6 +4019,7 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
3930 | struct fw_blob *blob; | 4019 | struct fw_blob *blob; |
3931 | uint32_t *fwcode, fwclen; | 4020 | uint32_t *fwcode, fwclen; |
3932 | struct qla_hw_data *ha = vha->hw; | 4021 | struct qla_hw_data *ha = vha->hw; |
4022 | struct req_que *req = ha->req_q_map[0]; | ||
3933 | 4023 | ||
3934 | /* Load firmware blob. */ | 4024 | /* Load firmware blob. */ |
3935 | blob = qla2x00_request_firmware(vha); | 4025 | blob = qla2x00_request_firmware(vha); |
@@ -3947,7 +4037,7 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
3947 | rval = QLA_SUCCESS; | 4037 | rval = QLA_SUCCESS; |
3948 | 4038 | ||
3949 | segments = FA_RISC_CODE_SEGMENTS; | 4039 | segments = FA_RISC_CODE_SEGMENTS; |
3950 | dcode = (uint32_t *)ha->req->ring; | 4040 | dcode = (uint32_t *)req->ring; |
3951 | *srisc_addr = 0; | 4041 | *srisc_addr = 0; |
3952 | fwcode = (uint32_t *)blob->fw->data; | 4042 | fwcode = (uint32_t *)blob->fw->data; |
3953 | fwclen = 0; | 4043 | fwclen = 0; |
@@ -4001,7 +4091,7 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
4001 | for (i = 0; i < dlen; i++) | 4091 | for (i = 0; i < dlen; i++) |
4002 | dcode[i] = swab32(fwcode[i]); | 4092 | dcode[i] = swab32(fwcode[i]); |
4003 | 4093 | ||
4004 | rval = qla2x00_load_ram(vha, ha->req->dma, risc_addr, | 4094 | rval = qla2x00_load_ram(vha, req->dma, risc_addr, |
4005 | dlen); | 4095 | dlen); |
4006 | if (rval) { | 4096 | if (rval) { |
4007 | DEBUG(printk("scsi(%ld):[ERROR] Failed to load " | 4097 | DEBUG(printk("scsi(%ld):[ERROR] Failed to load " |
@@ -4060,6 +4150,8 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha) | |||
4060 | uint16_t mb[MAILBOX_REGISTER_COUNT]; | 4150 | uint16_t mb[MAILBOX_REGISTER_COUNT]; |
4061 | struct qla_hw_data *ha = vha->hw; | 4151 | struct qla_hw_data *ha = vha->hw; |
4062 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); | 4152 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
4153 | struct req_que *req = ha->req_q_map[0]; | ||
4154 | struct rsp_que *rsp = ha->rsp_q_map[0]; | ||
4063 | 4155 | ||
4064 | if (!vha->vp_idx) | 4156 | if (!vha->vp_idx) |
4065 | return -EINVAL; | 4157 | return -EINVAL; |
@@ -4067,7 +4159,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha) | |||
4067 | rval = qla2x00_fw_ready(base_vha); | 4159 | rval = qla2x00_fw_ready(base_vha); |
4068 | if (rval == QLA_SUCCESS) { | 4160 | if (rval == QLA_SUCCESS) { |
4069 | clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); | 4161 | clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); |
4070 | qla2x00_marker(vha, 0, 0, MK_SYNC_ALL); | 4162 | qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); |
4071 | } | 4163 | } |
4072 | 4164 | ||
4073 | vha->flags.management_server_logged_in = 0; | 4165 | vha->flags.management_server_logged_in = 0; |