aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_mbx.c
diff options
context:
space:
mode:
authorAnirban Chakraborty <anirban.chakraborty@qlogic.com>2008-12-09 19:45:39 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-12-29 12:24:33 -0500
commit73208dfd7ab19f379d73e8a0fbf30f92c203e5e8 (patch)
treef69be5e89817d17b066ece4dbe04e395339c0754 /drivers/scsi/qla2xxx/qla_mbx.c
parent85b4aa4926a50210b683ac89326e338e7d131211 (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_mbx.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c147
1 files changed, 133 insertions, 14 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index bbe7181fb3d5..c54bc977c7b8 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -153,7 +153,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
153 break; 153 break;
154 154
155 /* Check for pending interrupts. */ 155 /* Check for pending interrupts. */
156 qla2x00_poll(ha->rsp); 156 qla2x00_poll(ha->rsp_q_map[0]);
157 157
158 if (command != MBC_LOAD_RISC_RAM_EXTENDED && 158 if (command != MBC_LOAD_RISC_RAM_EXTENDED &&
159 !ha->flags.mbox_int) 159 !ha->flags.mbox_int)
@@ -223,7 +223,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
223 "interrupt.\n", __func__, base_vha->host_no)); 223 "interrupt.\n", __func__, base_vha->host_no));
224 224
225 /* polling mode for non isp_abort commands. */ 225 /* polling mode for non isp_abort commands. */
226 qla2x00_poll(ha->rsp); 226 qla2x00_poll(ha->rsp_q_map[0]);
227 } 227 }
228 228
229 if (rval == QLA_FUNCTION_TIMEOUT && 229 if (rval == QLA_FUNCTION_TIMEOUT &&
@@ -713,8 +713,6 @@ qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
713 /*EMPTY*/ 713 /*EMPTY*/
714 DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", 714 DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n",
715 vha->host_no, rval)); 715 vha->host_no, rval));
716 DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n",
717 vha->host_no, rval));
718 } else { 716 } else {
719 sts_entry_t *sts_entry = (sts_entry_t *) buffer; 717 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
720 718
@@ -749,16 +747,15 @@ qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
749 * Kernel context. 747 * Kernel context.
750 */ 748 */
751int 749int
752qla2x00_abort_command(scsi_qla_host_t *vha, srb_t *sp) 750qla2x00_abort_command(scsi_qla_host_t *vha, srb_t *sp, struct req_que *req)
753{ 751{
754 unsigned long flags = 0; 752 unsigned long flags = 0;
755 fc_port_t *fcport; 753 fc_port_t *fcport;
756 int rval; 754 int rval;
757 uint32_t handle; 755 uint32_t handle = 0;
758 mbx_cmd_t mc; 756 mbx_cmd_t mc;
759 mbx_cmd_t *mcp = &mc; 757 mbx_cmd_t *mcp = &mc;
760 struct qla_hw_data *ha = vha->hw; 758 struct qla_hw_data *ha = vha->hw;
761 struct req_que *req = ha->req;
762 759
763 DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", vha->host_no)); 760 DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", vha->host_no));
764 761
@@ -808,11 +805,15 @@ qla2x00_abort_target(struct fc_port *fcport, unsigned int l)
808 mbx_cmd_t mc; 805 mbx_cmd_t mc;
809 mbx_cmd_t *mcp = &mc; 806 mbx_cmd_t *mcp = &mc;
810 scsi_qla_host_t *vha; 807 scsi_qla_host_t *vha;
808 struct req_que *req;
809 struct rsp_que *rsp;
811 810
812 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no)); 811 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no));
813 812
814 l = l; 813 l = l;
815 vha = fcport->vha; 814 vha = fcport->vha;
815 req = vha->hw->req_q_map[0];
816 rsp = vha->hw->rsp_q_map[0];
816 mcp->mb[0] = MBC_ABORT_TARGET; 817 mcp->mb[0] = MBC_ABORT_TARGET;
817 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0; 818 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
818 if (HAS_EXTENDED_IDS(vha->hw)) { 819 if (HAS_EXTENDED_IDS(vha->hw)) {
@@ -835,7 +836,8 @@ qla2x00_abort_target(struct fc_port *fcport, unsigned int l)
835 } 836 }
836 837
837 /* Issue marker IOCB. */ 838 /* Issue marker IOCB. */
838 rval2 = qla2x00_marker(vha, fcport->loop_id, 0, MK_SYNC_ID); 839 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
840 MK_SYNC_ID);
839 if (rval2 != QLA_SUCCESS) { 841 if (rval2 != QLA_SUCCESS) {
840 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " 842 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
841 "(%x).\n", __func__, vha->host_no, rval2)); 843 "(%x).\n", __func__, vha->host_no, rval2));
@@ -853,10 +855,14 @@ qla2x00_lun_reset(struct fc_port *fcport, unsigned int l)
853 mbx_cmd_t mc; 855 mbx_cmd_t mc;
854 mbx_cmd_t *mcp = &mc; 856 mbx_cmd_t *mcp = &mc;
855 scsi_qla_host_t *vha; 857 scsi_qla_host_t *vha;
858 struct req_que *req;
859 struct rsp_que *rsp;
856 860
857 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no)); 861 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no));
858 862
859 vha = fcport->vha; 863 vha = fcport->vha;
864 req = vha->hw->req_q_map[0];
865 rsp = vha->hw->rsp_q_map[0];
860 mcp->mb[0] = MBC_LUN_RESET; 866 mcp->mb[0] = MBC_LUN_RESET;
861 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; 867 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
862 if (HAS_EXTENDED_IDS(vha->hw)) 868 if (HAS_EXTENDED_IDS(vha->hw))
@@ -877,7 +883,8 @@ qla2x00_lun_reset(struct fc_port *fcport, unsigned int l)
877 } 883 }
878 884
879 /* Issue marker IOCB. */ 885 /* Issue marker IOCB. */
880 rval2 = qla2x00_marker(vha, fcport->loop_id, l, MK_SYNC_ID_LUN); 886 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
887 MK_SYNC_ID_LUN);
881 if (rval2 != QLA_SUCCESS) { 888 if (rval2 != QLA_SUCCESS) {
882 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " 889 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
883 "(%x).\n", __func__, vha->host_no, rval2)); 890 "(%x).\n", __func__, vha->host_no, rval2));
@@ -1743,6 +1750,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
1743 lg->port_id[1] = area; 1750 lg->port_id[1] = area;
1744 lg->port_id[2] = domain; 1751 lg->port_id[2] = domain;
1745 lg->vp_index = vha->vp_idx; 1752 lg->vp_index = vha->vp_idx;
1753
1746 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0); 1754 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
1747 if (rval != QLA_SUCCESS) { 1755 if (rval != QLA_SUCCESS) {
1748 DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB " 1756 DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB "
@@ -1753,9 +1761,9 @@ qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
1753 lg->entry_status)); 1761 lg->entry_status));
1754 rval = QLA_FUNCTION_FAILED; 1762 rval = QLA_FUNCTION_FAILED;
1755 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) { 1763 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1756 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " 1764 DEBUG2_3_11(printk("%s(%ld %d): failed to complete IOCB "
1757 "-- completion status (%x) ioparam=%x/%x.\n", __func__, 1765 "-- completion status (%x) ioparam=%x/%x.\n", __func__,
1758 vha->host_no, le16_to_cpu(lg->comp_status), 1766 vha->host_no, vha->vp_idx, le16_to_cpu(lg->comp_status),
1759 le32_to_cpu(lg->io_parameter[0]), 1767 le32_to_cpu(lg->io_parameter[0]),
1760 le32_to_cpu(lg->io_parameter[1]))); 1768 le32_to_cpu(lg->io_parameter[1])));
1761 } else { 1769 } else {
@@ -2173,7 +2181,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
2173} 2181}
2174 2182
2175int 2183int
2176qla24xx_abort_command(scsi_qla_host_t *vha, srb_t *sp) 2184qla24xx_abort_command(scsi_qla_host_t *vha, srb_t *sp, struct req_que *req)
2177{ 2185{
2178 int rval; 2186 int rval;
2179 fc_port_t *fcport; 2187 fc_port_t *fcport;
@@ -2183,7 +2191,6 @@ qla24xx_abort_command(scsi_qla_host_t *vha, srb_t *sp)
2183 dma_addr_t abt_dma; 2191 dma_addr_t abt_dma;
2184 uint32_t handle; 2192 uint32_t handle;
2185 struct qla_hw_data *ha = vha->hw; 2193 struct qla_hw_data *ha = vha->hw;
2186 struct req_que *req = ha->req;
2187 2194
2188 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); 2195 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
2189 2196
@@ -2216,6 +2223,9 @@ qla24xx_abort_command(scsi_qla_host_t *vha, srb_t *sp)
2216 abt->port_id[1] = fcport->d_id.b.area; 2223 abt->port_id[1] = fcport->d_id.b.area;
2217 abt->port_id[2] = fcport->d_id.b.domain; 2224 abt->port_id[2] = fcport->d_id.b.domain;
2218 abt->vp_index = fcport->vp_idx; 2225 abt->vp_index = fcport->vp_idx;
2226
2227 abt->req_que_no = cpu_to_le16(req->id);
2228
2219 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0); 2229 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
2220 if (rval != QLA_SUCCESS) { 2230 if (rval != QLA_SUCCESS) {
2221 DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n", 2231 DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n",
@@ -2255,11 +2265,15 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
2255 dma_addr_t tsk_dma; 2265 dma_addr_t tsk_dma;
2256 scsi_qla_host_t *vha; 2266 scsi_qla_host_t *vha;
2257 struct qla_hw_data *ha; 2267 struct qla_hw_data *ha;
2268 struct req_que *req;
2269 struct rsp_que *rsp;
2258 2270
2259 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no)); 2271 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no));
2260 2272
2261 vha = fcport->vha; 2273 vha = fcport->vha;
2262 ha = vha->hw; 2274 ha = vha->hw;
2275 req = ha->req_q_map[0];
2276 rsp = ha->rsp_q_map[0];
2263 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); 2277 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
2264 if (tsk == NULL) { 2278 if (tsk == NULL) {
2265 DEBUG2_3(printk("%s(%ld): failed to allocate Task Management " 2279 DEBUG2_3(printk("%s(%ld): failed to allocate Task Management "
@@ -2301,7 +2315,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
2301 } 2315 }
2302 2316
2303 /* Issue marker IOCB. */ 2317 /* Issue marker IOCB. */
2304 rval2 = qla2x00_marker(vha, fcport->loop_id, l, 2318 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
2305 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID); 2319 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2306 if (rval2 != QLA_SUCCESS) { 2320 if (rval2 != QLA_SUCCESS) {
2307 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " 2321 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
@@ -3069,3 +3083,108 @@ verify_done:
3069 3083
3070 return rval; 3084 return rval;
3071} 3085}
3086
3087int
3088qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req,
3089 uint8_t options)
3090{
3091 int rval;
3092 unsigned long flags;
3093 mbx_cmd_t mc;
3094 mbx_cmd_t *mcp = &mc;
3095 struct device_reg_25xxmq __iomem *reg;
3096 struct qla_hw_data *ha = vha->hw;
3097
3098 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
3099 mcp->mb[1] = options;
3100 mcp->mb[2] = MSW(LSD(req->dma));
3101 mcp->mb[3] = LSW(LSD(req->dma));
3102 mcp->mb[6] = MSW(MSD(req->dma));
3103 mcp->mb[7] = LSW(MSD(req->dma));
3104 mcp->mb[5] = req->length;
3105 if (req->rsp)
3106 mcp->mb[10] = req->rsp->id;
3107 mcp->mb[12] = req->qos;
3108 mcp->mb[11] = req->vp_idx;
3109 mcp->mb[13] = req->rid;
3110
3111 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3112 QLA_QUE_PAGE * req->id);
3113
3114 mcp->mb[4] = req->id;
3115 /* que in ptr index */
3116 mcp->mb[8] = 0;
3117 /* que out ptr index */
3118 mcp->mb[9] = 0;
3119 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3120 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3121 mcp->in_mb = MBX_0;
3122 mcp->flags = MBX_DMA_OUT;
3123 mcp->tov = 60;
3124
3125 spin_lock_irqsave(&ha->hardware_lock, flags);
3126 if (!(options & BIT_0)) {
3127 WRT_REG_DWORD(&reg->req_q_in, 0);
3128 WRT_REG_DWORD(&reg->req_q_out, 0);
3129 }
3130 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3131
3132 rval = (int)qla2x00_mailbox_command(vha, mcp);
3133 if (rval != QLA_SUCCESS)
3134 DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x mb0=%x.\n",
3135 __func__, vha->host_no, rval, mcp->mb[0]));
3136 return rval;
3137}
3138
3139int
3140qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp,
3141 uint8_t options)
3142{
3143 int rval;
3144 unsigned long flags;
3145 mbx_cmd_t mc;
3146 mbx_cmd_t *mcp = &mc;
3147 struct device_reg_25xxmq __iomem *reg;
3148 struct qla_hw_data *ha = vha->hw;
3149
3150 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
3151 mcp->mb[1] = options;
3152 mcp->mb[2] = MSW(LSD(rsp->dma));
3153 mcp->mb[3] = LSW(LSD(rsp->dma));
3154 mcp->mb[6] = MSW(MSD(rsp->dma));
3155 mcp->mb[7] = LSW(MSD(rsp->dma));
3156 mcp->mb[5] = rsp->length;
3157 mcp->mb[11] = rsp->vp_idx;
3158 mcp->mb[14] = rsp->msix->vector;
3159 mcp->mb[13] = rsp->rid;
3160
3161 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3162 QLA_QUE_PAGE * rsp->id);
3163
3164 mcp->mb[4] = rsp->id;
3165 /* que in ptr index */
3166 mcp->mb[8] = 0;
3167 /* que out ptr index */
3168 mcp->mb[9] = 0;
3169 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7
3170 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3171 mcp->in_mb = MBX_0;
3172 mcp->flags = MBX_DMA_OUT;
3173 mcp->tov = 60;
3174
3175 spin_lock_irqsave(&ha->hardware_lock, flags);
3176 if (!(options & BIT_0)) {
3177 WRT_REG_DWORD(&reg->rsp_q_out, 0);
3178 WRT_REG_DWORD(&reg->rsp_q_in, 0);
3179 }
3180
3181 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3182
3183 rval = (int)qla2x00_mailbox_command(vha, mcp);
3184 if (rval != QLA_SUCCESS)
3185 DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x "
3186 "mb0=%x.\n", __func__,
3187 vha->host_no, rval, mcp->mb[0]));
3188 return rval;
3189}
3190