aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Soni Jose <sony.john-n@emulex.com>2012-10-19 19:14:23 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-11-26 23:59:39 -0500
commit09a1093a292aa88af836f4fb3b604af9aa1ece3d (patch)
tree29ec5e18d6072984a10942a914892a15f5bdfe66
parenteaae5267de0b199720e8df6124685268b6258015 (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.c265
-rw-r--r--drivers/scsi/be2iscsi/be_main.h51
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
2155static void 2155static void
2156hwi_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
2250static void
2156hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg, 2251hwi_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}
4349int 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
4245static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, 4406static 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
350struct beiscsi_session { 353struct 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
423struct be_nonio_bhs { 427struct 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
683struct 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
674struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid); 723struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid);
675void 724void
676free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); 725free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);