diff options
author | John Soni Jose <sony.john-n@emulex.com> | 2012-10-19 19:14:23 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-11-26 23:59:39 -0500 |
commit | 09a1093a292aa88af836f4fb3b604af9aa1ece3d (patch) | |
tree | 29ec5e18d6072984a10942a914892a15f5bdfe66 | |
parent | eaae5267de0b199720e8df6124685268b6258015 (diff) |
[SCSI] be2iscsi: Fix support for V2 version of WRB.
Latest adapters use the V2 version of WRB. This fix checks for the
adapter type and uses appropriate version of WRB.
Signed-off-by: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 265 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 51 |
2 files changed, 277 insertions, 39 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 8a142cee8a56..6aef05f78449 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -2153,6 +2153,101 @@ static int be_iopoll(struct blk_iopoll *iop, int budget) | |||
2153 | } | 2153 | } |
2154 | 2154 | ||
2155 | static void | 2155 | static void |
2156 | hwi_write_sgl_v2(struct iscsi_wrb *pwrb, struct scatterlist *sg, | ||
2157 | unsigned int num_sg, struct beiscsi_io_task *io_task) | ||
2158 | { | ||
2159 | struct iscsi_sge *psgl; | ||
2160 | unsigned int sg_len, index; | ||
2161 | unsigned int sge_len = 0; | ||
2162 | unsigned long long addr; | ||
2163 | struct scatterlist *l_sg; | ||
2164 | unsigned int offset; | ||
2165 | |||
2166 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, iscsi_bhs_addr_lo, pwrb, | ||
2167 | io_task->bhs_pa.u.a32.address_lo); | ||
2168 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, iscsi_bhs_addr_hi, pwrb, | ||
2169 | io_task->bhs_pa.u.a32.address_hi); | ||
2170 | |||
2171 | l_sg = sg; | ||
2172 | for (index = 0; (index < num_sg) && (index < 2); index++, | ||
2173 | sg = sg_next(sg)) { | ||
2174 | if (index == 0) { | ||
2175 | sg_len = sg_dma_len(sg); | ||
2176 | addr = (u64) sg_dma_address(sg); | ||
2177 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, | ||
2178 | sge0_addr_lo, pwrb, | ||
2179 | lower_32_bits(addr)); | ||
2180 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, | ||
2181 | sge0_addr_hi, pwrb, | ||
2182 | upper_32_bits(addr)); | ||
2183 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, | ||
2184 | sge0_len, pwrb, | ||
2185 | sg_len); | ||
2186 | sge_len = sg_len; | ||
2187 | } else { | ||
2188 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, sge1_r2t_offset, | ||
2189 | pwrb, sge_len); | ||
2190 | sg_len = sg_dma_len(sg); | ||
2191 | addr = (u64) sg_dma_address(sg); | ||
2192 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, | ||
2193 | sge1_addr_lo, pwrb, | ||
2194 | lower_32_bits(addr)); | ||
2195 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, | ||
2196 | sge1_addr_hi, pwrb, | ||
2197 | upper_32_bits(addr)); | ||
2198 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, | ||
2199 | sge1_len, pwrb, | ||
2200 | sg_len); | ||
2201 | } | ||
2202 | } | ||
2203 | psgl = (struct iscsi_sge *)io_task->psgl_handle->pfrag; | ||
2204 | memset(psgl, 0, sizeof(*psgl) * BE2_SGE); | ||
2205 | |||
2206 | AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, io_task->bhs_len - 2); | ||
2207 | |||
2208 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl, | ||
2209 | io_task->bhs_pa.u.a32.address_hi); | ||
2210 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, | ||
2211 | io_task->bhs_pa.u.a32.address_lo); | ||
2212 | |||
2213 | if (num_sg == 1) { | ||
2214 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, sge0_last, pwrb, | ||
2215 | 1); | ||
2216 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, sge1_last, pwrb, | ||
2217 | 0); | ||
2218 | } else if (num_sg == 2) { | ||
2219 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, sge0_last, pwrb, | ||
2220 | 0); | ||
2221 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, sge1_last, pwrb, | ||
2222 | 1); | ||
2223 | } else { | ||
2224 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, sge0_last, pwrb, | ||
2225 | 0); | ||
2226 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, sge1_last, pwrb, | ||
2227 | 0); | ||
2228 | } | ||
2229 | |||
2230 | sg = l_sg; | ||
2231 | psgl++; | ||
2232 | psgl++; | ||
2233 | offset = 0; | ||
2234 | for (index = 0; index < num_sg; index++, sg = sg_next(sg), psgl++) { | ||
2235 | sg_len = sg_dma_len(sg); | ||
2236 | addr = (u64) sg_dma_address(sg); | ||
2237 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, | ||
2238 | lower_32_bits(addr)); | ||
2239 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl, | ||
2240 | upper_32_bits(addr)); | ||
2241 | AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, sg_len); | ||
2242 | AMAP_SET_BITS(struct amap_iscsi_sge, sge_offset, psgl, offset); | ||
2243 | AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 0); | ||
2244 | offset += sg_len; | ||
2245 | } | ||
2246 | psgl--; | ||
2247 | AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1); | ||
2248 | } | ||
2249 | |||
2250 | static void | ||
2156 | hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg, | 2251 | hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg, |
2157 | unsigned int num_sg, struct beiscsi_io_task *io_task) | 2252 | unsigned int num_sg, struct beiscsi_io_task *io_task) |
2158 | { | 2253 | { |
@@ -2251,6 +2346,7 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task) | |||
2251 | struct beiscsi_io_task *io_task = task->dd_data; | 2346 | struct beiscsi_io_task *io_task = task->dd_data; |
2252 | struct beiscsi_conn *beiscsi_conn = io_task->conn; | 2347 | struct beiscsi_conn *beiscsi_conn = io_task->conn; |
2253 | struct beiscsi_hba *phba = beiscsi_conn->phba; | 2348 | struct beiscsi_hba *phba = beiscsi_conn->phba; |
2349 | uint8_t dsp_value = 0; | ||
2254 | 2350 | ||
2255 | io_task->bhs_len = sizeof(struct be_nonio_bhs) - 2; | 2351 | io_task->bhs_len = sizeof(struct be_nonio_bhs) - 2; |
2256 | AMAP_SET_BITS(struct amap_iscsi_wrb, iscsi_bhs_addr_lo, pwrb, | 2352 | AMAP_SET_BITS(struct amap_iscsi_wrb, iscsi_bhs_addr_lo, pwrb, |
@@ -2259,18 +2355,27 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task) | |||
2259 | io_task->bhs_pa.u.a32.address_hi); | 2355 | io_task->bhs_pa.u.a32.address_hi); |
2260 | 2356 | ||
2261 | if (task->data) { | 2357 | if (task->data) { |
2262 | if (task->data_count) { | 2358 | |
2263 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); | 2359 | /* Check for the data_count */ |
2360 | dsp_value = (task->data_count) ? 1 : 0; | ||
2361 | |||
2362 | if (chip_skh_r(phba->pcidev)) | ||
2363 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, dsp, | ||
2364 | pwrb, dsp_value); | ||
2365 | else | ||
2366 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, | ||
2367 | pwrb, dsp_value); | ||
2368 | |||
2369 | /* Map addr only if there is data_count */ | ||
2370 | if (dsp_value) { | ||
2264 | io_task->mtask_addr = pci_map_single(phba->pcidev, | 2371 | io_task->mtask_addr = pci_map_single(phba->pcidev, |
2265 | task->data, | 2372 | task->data, |
2266 | task->data_count, | 2373 | task->data_count, |
2267 | PCI_DMA_TODEVICE); | 2374 | PCI_DMA_TODEVICE); |
2268 | |||
2269 | io_task->mtask_data_count = task->data_count; | 2375 | io_task->mtask_data_count = task->data_count; |
2270 | } else { | 2376 | } else |
2271 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); | ||
2272 | io_task->mtask_addr = 0; | 2377 | io_task->mtask_addr = 0; |
2273 | } | 2378 | |
2274 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb, | 2379 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb, |
2275 | lower_32_bits(io_task->mtask_addr)); | 2380 | lower_32_bits(io_task->mtask_addr)); |
2276 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb, | 2381 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb, |
@@ -4241,6 +4346,62 @@ free_hndls: | |||
4241 | io_task->cmd_bhs = NULL; | 4346 | io_task->cmd_bhs = NULL; |
4242 | return -ENOMEM; | 4347 | return -ENOMEM; |
4243 | } | 4348 | } |
4349 | int beiscsi_iotask_v2(struct iscsi_task *task, struct scatterlist *sg, | ||
4350 | unsigned int num_sg, unsigned int xferlen, | ||
4351 | unsigned int writedir) | ||
4352 | { | ||
4353 | |||
4354 | struct beiscsi_io_task *io_task = task->dd_data; | ||
4355 | struct iscsi_conn *conn = task->conn; | ||
4356 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; | ||
4357 | struct beiscsi_hba *phba = beiscsi_conn->phba; | ||
4358 | struct iscsi_wrb *pwrb = NULL; | ||
4359 | unsigned int doorbell = 0; | ||
4360 | |||
4361 | pwrb = io_task->pwrb_handle->pwrb; | ||
4362 | memset(pwrb, 0, sizeof(*pwrb)); | ||
4363 | |||
4364 | io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0; | ||
4365 | io_task->bhs_len = sizeof(struct be_cmd_bhs); | ||
4366 | |||
4367 | if (writedir) { | ||
4368 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, type, pwrb, | ||
4369 | INI_WR_CMD); | ||
4370 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, dsp, pwrb, 1); | ||
4371 | } else { | ||
4372 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, type, pwrb, | ||
4373 | INI_RD_CMD); | ||
4374 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, dsp, pwrb, 0); | ||
4375 | } | ||
4376 | |||
4377 | io_task->wrb_type = AMAP_GET_BITS(struct amap_iscsi_wrb_v2, | ||
4378 | type, pwrb); | ||
4379 | |||
4380 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, lun, pwrb, | ||
4381 | cpu_to_be16(*(unsigned short *) | ||
4382 | &io_task->cmd_bhs->iscsi_hdr.lun)); | ||
4383 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, r2t_exp_dtl, pwrb, xferlen); | ||
4384 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, wrb_idx, pwrb, | ||
4385 | io_task->pwrb_handle->wrb_index); | ||
4386 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, cmdsn_itt, pwrb, | ||
4387 | be32_to_cpu(task->cmdsn)); | ||
4388 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, sgl_idx, pwrb, | ||
4389 | io_task->psgl_handle->sgl_index); | ||
4390 | |||
4391 | hwi_write_sgl_v2(pwrb, sg, num_sg, io_task); | ||
4392 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb, pwrb, | ||
4393 | io_task->pwrb_handle->nxt_wrb_index); | ||
4394 | |||
4395 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); | ||
4396 | |||
4397 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; | ||
4398 | doorbell |= (io_task->pwrb_handle->wrb_index & | ||
4399 | DB_DEF_PDU_WRB_INDEX_MASK) << | ||
4400 | DB_DEF_PDU_WRB_INDEX_SHIFT; | ||
4401 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | ||
4402 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); | ||
4403 | return 0; | ||
4404 | } | ||
4244 | 4405 | ||
4245 | static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, | 4406 | static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, |
4246 | unsigned int num_sg, unsigned int xferlen, | 4407 | unsigned int num_sg, unsigned int xferlen, |
@@ -4268,6 +4429,9 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, | |||
4268 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); | 4429 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); |
4269 | } | 4430 | } |
4270 | 4431 | ||
4432 | io_task->wrb_type = AMAP_GET_BITS(struct amap_iscsi_wrb, | ||
4433 | type, pwrb); | ||
4434 | |||
4271 | AMAP_SET_BITS(struct amap_iscsi_wrb, lun, pwrb, | 4435 | AMAP_SET_BITS(struct amap_iscsi_wrb, lun, pwrb, |
4272 | cpu_to_be16(*(unsigned short *) | 4436 | cpu_to_be16(*(unsigned short *) |
4273 | &io_task->cmd_bhs->iscsi_hdr.lun)); | 4437 | &io_task->cmd_bhs->iscsi_hdr.lun)); |
@@ -4303,55 +4467,75 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
4303 | struct iscsi_wrb *pwrb = NULL; | 4467 | struct iscsi_wrb *pwrb = NULL; |
4304 | unsigned int doorbell = 0; | 4468 | unsigned int doorbell = 0; |
4305 | unsigned int cid; | 4469 | unsigned int cid; |
4470 | unsigned int pwrb_typeoffset = 0; | ||
4306 | 4471 | ||
4307 | cid = beiscsi_conn->beiscsi_conn_cid; | 4472 | cid = beiscsi_conn->beiscsi_conn_cid; |
4308 | pwrb = io_task->pwrb_handle->pwrb; | 4473 | pwrb = io_task->pwrb_handle->pwrb; |
4309 | memset(pwrb, 0, sizeof(*pwrb)); | 4474 | memset(pwrb, 0, sizeof(*pwrb)); |
4310 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, | 4475 | |
4311 | be32_to_cpu(task->cmdsn)); | 4476 | if (chip_skh_r(phba->pcidev)) { |
4312 | AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb, | 4477 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, cmdsn_itt, pwrb, |
4313 | io_task->pwrb_handle->wrb_index); | 4478 | be32_to_cpu(task->cmdsn)); |
4314 | AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, | 4479 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, wrb_idx, pwrb, |
4315 | io_task->psgl_handle->sgl_index); | 4480 | io_task->pwrb_handle->wrb_index); |
4481 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, sgl_idx, pwrb, | ||
4482 | io_task->psgl_handle->sgl_index); | ||
4483 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, r2t_exp_dtl, pwrb, | ||
4484 | task->data_count); | ||
4485 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb, pwrb, | ||
4486 | io_task->pwrb_handle->nxt_wrb_index); | ||
4487 | pwrb_typeoffset = SKH_WRB_TYPE_OFFSET; | ||
4488 | } else { | ||
4489 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, | ||
4490 | be32_to_cpu(task->cmdsn)); | ||
4491 | AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb, | ||
4492 | io_task->pwrb_handle->wrb_index); | ||
4493 | AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, | ||
4494 | io_task->psgl_handle->sgl_index); | ||
4495 | AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, | ||
4496 | task->data_count); | ||
4497 | AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb, | ||
4498 | io_task->pwrb_handle->nxt_wrb_index); | ||
4499 | pwrb_typeoffset = BE_WRB_TYPE_OFFSET; | ||
4500 | } | ||
4501 | |||
4316 | 4502 | ||
4317 | switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { | 4503 | switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { |
4318 | case ISCSI_OP_LOGIN: | 4504 | case ISCSI_OP_LOGIN: |
4319 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
4320 | TGT_DM_CMD); | ||
4321 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | ||
4322 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1); | 4505 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1); |
4506 | ADAPTER_SET_WRB_TYPE(pwrb, TGT_DM_CMD, pwrb_typeoffset); | ||
4323 | hwi_write_buffer(pwrb, task); | 4507 | hwi_write_buffer(pwrb, task); |
4324 | break; | 4508 | break; |
4325 | case ISCSI_OP_NOOP_OUT: | 4509 | case ISCSI_OP_NOOP_OUT: |
4326 | if (task->hdr->ttt != ISCSI_RESERVED_TAG) { | 4510 | if (task->hdr->ttt != ISCSI_RESERVED_TAG) { |
4327 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 4511 | ADAPTER_SET_WRB_TYPE(pwrb, TGT_DM_CMD, pwrb_typeoffset); |
4328 | TGT_DM_CMD); | 4512 | if (chip_skh_r(phba->pcidev)) |
4329 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, | 4513 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, |
4330 | pwrb, 0); | 4514 | dmsg, pwrb, 1); |
4331 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1); | 4515 | else |
4516 | AMAP_SET_BITS(struct amap_iscsi_wrb, | ||
4517 | dmsg, pwrb, 1); | ||
4332 | } else { | 4518 | } else { |
4333 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 4519 | ADAPTER_SET_WRB_TYPE(pwrb, INI_RD_CMD, pwrb_typeoffset); |
4334 | INI_RD_CMD); | 4520 | if (chip_skh_r(phba->pcidev)) |
4335 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 4521 | AMAP_SET_BITS(struct amap_iscsi_wrb_v2, |
4522 | dmsg, pwrb, 0); | ||
4523 | else | ||
4524 | AMAP_SET_BITS(struct amap_iscsi_wrb, | ||
4525 | dmsg, pwrb, 0); | ||
4336 | } | 4526 | } |
4337 | hwi_write_buffer(pwrb, task); | 4527 | hwi_write_buffer(pwrb, task); |
4338 | break; | 4528 | break; |
4339 | case ISCSI_OP_TEXT: | 4529 | case ISCSI_OP_TEXT: |
4340 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 4530 | ADAPTER_SET_WRB_TYPE(pwrb, TGT_DM_CMD, pwrb_typeoffset); |
4341 | TGT_DM_CMD); | ||
4342 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | ||
4343 | hwi_write_buffer(pwrb, task); | 4531 | hwi_write_buffer(pwrb, task); |
4344 | break; | 4532 | break; |
4345 | case ISCSI_OP_SCSI_TMFUNC: | 4533 | case ISCSI_OP_SCSI_TMFUNC: |
4346 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 4534 | ADAPTER_SET_WRB_TYPE(pwrb, INI_TMF_CMD, pwrb_typeoffset); |
4347 | INI_TMF_CMD); | ||
4348 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | ||
4349 | hwi_write_buffer(pwrb, task); | 4535 | hwi_write_buffer(pwrb, task); |
4350 | break; | 4536 | break; |
4351 | case ISCSI_OP_LOGOUT: | 4537 | case ISCSI_OP_LOGOUT: |
4352 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 4538 | ADAPTER_SET_WRB_TYPE(pwrb, HWH_TYPE_LOGOUT, pwrb_typeoffset); |
4353 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
4354 | HWH_TYPE_LOGOUT); | ||
4355 | hwi_write_buffer(pwrb, task); | 4539 | hwi_write_buffer(pwrb, task); |
4356 | break; | 4540 | break; |
4357 | 4541 | ||
@@ -4363,11 +4547,10 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
4363 | return -EINVAL; | 4547 | return -EINVAL; |
4364 | } | 4548 | } |
4365 | 4549 | ||
4366 | AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, | 4550 | /* Set the task type */ |
4367 | task->data_count); | 4551 | io_task->wrb_type = (chip_skh_r(phba->pcidev)) ? |
4368 | AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb, | 4552 | AMAP_GET_BITS(struct amap_iscsi_wrb_v2, type, pwrb) : |
4369 | io_task->pwrb_handle->nxt_wrb_index); | 4553 | AMAP_GET_BITS(struct amap_iscsi_wrb, type, pwrb); |
4370 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); | ||
4371 | 4554 | ||
4372 | doorbell |= cid & DB_WRB_POST_CID_MASK; | 4555 | doorbell |= cid & DB_WRB_POST_CID_MASK; |
4373 | doorbell |= (io_task->pwrb_handle->wrb_index & | 4556 | doorbell |= (io_task->pwrb_handle->wrb_index & |
@@ -4381,10 +4564,13 @@ static int beiscsi_task_xmit(struct iscsi_task *task) | |||
4381 | { | 4564 | { |
4382 | struct beiscsi_io_task *io_task = task->dd_data; | 4565 | struct beiscsi_io_task *io_task = task->dd_data; |
4383 | struct scsi_cmnd *sc = task->sc; | 4566 | struct scsi_cmnd *sc = task->sc; |
4567 | struct beiscsi_hba *phba = NULL; | ||
4384 | struct scatterlist *sg; | 4568 | struct scatterlist *sg; |
4385 | int num_sg; | 4569 | int num_sg; |
4386 | unsigned int writedir = 0, xferlen = 0; | 4570 | unsigned int writedir = 0, xferlen = 0; |
4387 | 4571 | ||
4572 | phba = ((struct beiscsi_conn *)task->conn->dd_data)->phba; | ||
4573 | |||
4388 | if (!sc) | 4574 | if (!sc) |
4389 | return beiscsi_mtask(task); | 4575 | return beiscsi_mtask(task); |
4390 | 4576 | ||
@@ -4407,7 +4593,7 @@ static int beiscsi_task_xmit(struct iscsi_task *task) | |||
4407 | else | 4593 | else |
4408 | writedir = 0; | 4594 | writedir = 0; |
4409 | 4595 | ||
4410 | return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); | 4596 | return phba->iotask_fn(task, sg, num_sg, xferlen, writedir); |
4411 | } | 4597 | } |
4412 | 4598 | ||
4413 | /** | 4599 | /** |
@@ -4618,13 +4804,16 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
4618 | case OC_DEVICE_ID1: | 4804 | case OC_DEVICE_ID1: |
4619 | case OC_DEVICE_ID2: | 4805 | case OC_DEVICE_ID2: |
4620 | phba->generation = BE_GEN2; | 4806 | phba->generation = BE_GEN2; |
4807 | phba->iotask_fn = beiscsi_iotask; | ||
4621 | break; | 4808 | break; |
4622 | case BE_DEVICE_ID2: | 4809 | case BE_DEVICE_ID2: |
4623 | case OC_DEVICE_ID3: | 4810 | case OC_DEVICE_ID3: |
4624 | phba->generation = BE_GEN3; | 4811 | phba->generation = BE_GEN3; |
4812 | phba->iotask_fn = beiscsi_iotask; | ||
4625 | break; | 4813 | break; |
4626 | case OC_SKH_ID1: | 4814 | case OC_SKH_ID1: |
4627 | phba->generation = BE_GEN4; | 4815 | phba->generation = BE_GEN4; |
4816 | phba->iotask_fn = beiscsi_iotask_v2; | ||
4628 | default: | 4817 | default: |
4629 | phba->generation = 0; | 4818 | phba->generation = 0; |
4630 | } | 4819 | } |
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 2c9cba2533b9..8632927da1ef 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h | |||
@@ -344,7 +344,10 @@ struct beiscsi_hba { | |||
344 | struct invalidate_command_table inv_tbl[128]; | 344 | struct invalidate_command_table inv_tbl[128]; |
345 | 345 | ||
346 | unsigned int attr_log_enable; | 346 | unsigned int attr_log_enable; |
347 | 347 | int (*iotask_fn)(struct iscsi_task *, | |
348 | struct scatterlist *sg, | ||
349 | uint32_t num_sg, uint32_t xferlen, | ||
350 | uint32_t writedir); | ||
348 | }; | 351 | }; |
349 | 352 | ||
350 | struct beiscsi_session { | 353 | struct beiscsi_session { |
@@ -418,6 +421,7 @@ struct beiscsi_io_task { | |||
418 | unsigned short bhs_len; | 421 | unsigned short bhs_len; |
419 | dma_addr_t mtask_addr; | 422 | dma_addr_t mtask_addr; |
420 | uint32_t mtask_data_count; | 423 | uint32_t mtask_data_count; |
424 | uint8_t wrb_type; | ||
421 | }; | 425 | }; |
422 | 426 | ||
423 | struct be_nonio_bhs { | 427 | struct be_nonio_bhs { |
@@ -625,6 +629,11 @@ struct iscsi_wrb { | |||
625 | } __packed; | 629 | } __packed; |
626 | 630 | ||
627 | #define WRB_TYPE_MASK 0xF0000000 | 631 | #define WRB_TYPE_MASK 0xF0000000 |
632 | #define SKH_WRB_TYPE_OFFSET 27 | ||
633 | #define BE_WRB_TYPE_OFFSET 28 | ||
634 | |||
635 | #define ADAPTER_SET_WRB_TYPE(pwrb, wrb_type, type_offset) \ | ||
636 | (pwrb->dw[0] |= (wrb_type << type_offset)) | ||
628 | 637 | ||
629 | /** | 638 | /** |
630 | * Pseudo amap definition in which each bit of the actual structure is defined | 639 | * Pseudo amap definition in which each bit of the actual structure is defined |
@@ -671,6 +680,46 @@ struct amap_iscsi_wrb { | |||
671 | 680 | ||
672 | } __packed; | 681 | } __packed; |
673 | 682 | ||
683 | struct amap_iscsi_wrb_v2 { | ||
684 | u8 r2t_exp_dtl[25]; /* DWORD 0 */ | ||
685 | u8 rsvd0[2]; /* DWORD 0*/ | ||
686 | u8 type[5]; /* DWORD 0 */ | ||
687 | u8 ptr2nextwrb[8]; /* DWORD 1 */ | ||
688 | u8 wrb_idx[8]; /* DWORD 1 */ | ||
689 | u8 lun[16]; /* DWORD 1 */ | ||
690 | u8 sgl_idx[16]; /* DWORD 2 */ | ||
691 | u8 ref_sgl_icd_idx[16]; /* DWORD 2 */ | ||
692 | u8 exp_data_sn[32]; /* DWORD 3 */ | ||
693 | u8 iscsi_bhs_addr_hi[32]; /* DWORD 4 */ | ||
694 | u8 iscsi_bhs_addr_lo[32]; /* DWORD 5 */ | ||
695 | u8 cq_id[16]; /* DWORD 6 */ | ||
696 | u8 rsvd1[16]; /* DWORD 6 */ | ||
697 | u8 cmdsn_itt[32]; /* DWORD 7 */ | ||
698 | u8 sge0_addr_hi[32]; /* DWORD 8 */ | ||
699 | u8 sge0_addr_lo[32]; /* DWORD 9 */ | ||
700 | u8 sge0_offset[24]; /* DWORD 10 */ | ||
701 | u8 rsvd2[7]; /* DWORD 10 */ | ||
702 | u8 sge0_last; /* DWORD 10 */ | ||
703 | u8 sge0_len[17]; /* DWORD 11 */ | ||
704 | u8 rsvd3[7]; /* DWORD 11 */ | ||
705 | u8 diff_enbl; /* DWORD 11 */ | ||
706 | u8 u_run; /* DWORD 11 */ | ||
707 | u8 o_run; /* DWORD 11 */ | ||
708 | u8 invalid; /* DWORD 11 */ | ||
709 | u8 dsp; /* DWORD 11 */ | ||
710 | u8 dmsg; /* DWORD 11 */ | ||
711 | u8 rsvd4; /* DWORD 11 */ | ||
712 | u8 lt; /* DWORD 11 */ | ||
713 | u8 sge1_addr_hi[32]; /* DWORD 12 */ | ||
714 | u8 sge1_addr_lo[32]; /* DWORD 13 */ | ||
715 | u8 sge1_r2t_offset[24]; /* DWORD 14 */ | ||
716 | u8 rsvd5[7]; /* DWORD 14 */ | ||
717 | u8 sge1_last; /* DWORD 14 */ | ||
718 | u8 sge1_len[17]; /* DWORD 15 */ | ||
719 | u8 rsvd6[15]; /* DWORD 15 */ | ||
720 | } __packed; | ||
721 | |||
722 | |||
674 | struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid); | 723 | struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid); |
675 | void | 724 | void |
676 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); | 725 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); |