aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi
diff options
context:
space:
mode:
authorJohn Soni Jose <sony.john-n@emulex.com>2012-10-19 19:14:49 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-11-26 23:59:40 -0500
commit7313326125c8da52a10780b5af3b290fa9498dcb (patch)
treec5a4237364af2a9f12f558e4dc20c59b8006ede1 /drivers/scsi/be2iscsi
parentacb9693cb007e126fd313cb696dfbf5c214514cd (diff)
[SCSI] be2iscsi: Fix Task Completion Event handling
The completion events returned by adapter differs based on the adapter. This fix checks for the adapter type and process the completion event. 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>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h53
-rw-r--r--drivers/scsi/be2iscsi/be_main.c267
-rw-r--r--drivers/scsi/be2iscsi/be_main.h14
3 files changed, 230 insertions, 104 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index c560e9dbe7a9..135c0965578f 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -826,6 +826,59 @@ struct amap_sol_cqe_ring {
826 u8 valid; /* dword 3 */ 826 u8 valid; /* dword 3 */
827} __packed; 827} __packed;
828 828
829struct amap_sol_cqe_v2 {
830 u8 hw_sts[8]; /* dword 0 */
831 u8 i_sts[8]; /* dword 0 */
832 u8 wrb_index[16]; /* dword 0 */
833 u8 i_exp_cmd_sn[32]; /* dword 1 */
834 u8 code[6]; /* dword 2 */
835 u8 cmd_cmpl; /* dword 2 */
836 u8 rsvd0; /* dword 2 */
837 u8 i_cmd_wnd[8]; /* dword 2 */
838 u8 cid[13]; /* dword 2 */
839 u8 u; /* dword 2 */
840 u8 o; /* dword 2 */
841 u8 s; /* dword 2 */
842 u8 i_res_cnt[31]; /* dword 3 */
843 u8 valid; /* dword 3 */
844} __packed;
845
846struct common_sol_cqe {
847 u32 exp_cmdsn;
848 u32 res_cnt;
849 u16 wrb_index;
850 u16 cid;
851 u8 hw_sts;
852 u8 cmd_wnd;
853 u8 res_flag; /* the s feild of structure */
854 u8 i_resp; /* for skh if cmd_complete is set then i_sts is response */
855 u8 i_flags; /* for skh or the u and o feilds */
856 u8 i_sts; /* for skh if cmd_complete is not-set then i_sts is status */
857};
858
859/*** iSCSI ack/driver message completions ***/
860struct amap_it_dmsg_cqe {
861 u8 ack_num[32]; /* DWORD 0 */
862 u8 pdu_bytes_rcvd[32]; /* DWORD 1 */
863 u8 code[6]; /* DWORD 2 */
864 u8 cid[10]; /* DWORD 2 */
865 u8 wrb_idx[8]; /* DWORD 2 */
866 u8 rsvd0[8]; /* DWORD 2*/
867 u8 rsvd1[31]; /* DWORD 3*/
868 u8 valid; /* DWORD 3 */
869} __packed;
870
871struct amap_it_dmsg_cqe_v2 {
872 u8 ack_num[32]; /* DWORD 0 */
873 u8 pdu_bytes_rcvd[32]; /* DWORD 1 */
874 u8 code[6]; /* DWORD 2 */
875 u8 rsvd0[10]; /* DWORD 2 */
876 u8 wrb_idx[16]; /* DWORD 2 */
877 u8 rsvd1[16]; /* DWORD 3 */
878 u8 cid[13]; /* DWORD 3 */
879 u8 rsvd2[2]; /* DWORD 3 */
880 u8 valid; /* DWORD 3 */
881} __packed;
829 882
830 883
831/** 884/**
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 9e669cec3424..2d28cac34f55 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1248,7 +1248,8 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
1248 1248
1249static void 1249static void
1250be_complete_io(struct beiscsi_conn *beiscsi_conn, 1250be_complete_io(struct beiscsi_conn *beiscsi_conn,
1251 struct iscsi_task *task, struct sol_cqe *psol) 1251 struct iscsi_task *task,
1252 struct common_sol_cqe *csol_cqe)
1252{ 1253{
1253 struct beiscsi_io_task *io_task = task->dd_data; 1254 struct beiscsi_io_task *io_task = task->dd_data;
1254 struct be_status_bhs *sts_bhs = 1255 struct be_status_bhs *sts_bhs =
@@ -1258,20 +1259,14 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
1258 u32 resid = 0, exp_cmdsn, max_cmdsn; 1259 u32 resid = 0, exp_cmdsn, max_cmdsn;
1259 u8 rsp, status, flags; 1260 u8 rsp, status, flags;
1260 1261
1261 exp_cmdsn = (psol-> 1262 exp_cmdsn = csol_cqe->exp_cmdsn;
1262 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32] 1263 max_cmdsn = (csol_cqe->exp_cmdsn +
1263 & SOL_EXP_CMD_SN_MASK); 1264 csol_cqe->cmd_wnd - 1);
1264 max_cmdsn = ((psol-> 1265 rsp = csol_cqe->i_resp;
1265 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32] 1266 status = csol_cqe->i_sts;
1266 & SOL_EXP_CMD_SN_MASK) + 1267 flags = csol_cqe->i_flags;
1267 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) 1268 resid = csol_cqe->res_cnt;
1268 / 32] & SOL_CMD_WND_MASK) >> 24) - 1); 1269
1269 rsp = ((psol->dw[offsetof(struct amap_sol_cqe, i_resp) / 32]
1270 & SOL_RESP_MASK) >> 16);
1271 status = ((psol->dw[offsetof(struct amap_sol_cqe, i_sts) / 32]
1272 & SOL_STS_MASK) >> 8);
1273 flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
1274 & SOL_FLAGS_MASK) >> 24) | 0x80;
1275 if (!task->sc) { 1270 if (!task->sc) {
1276 if (io_task->scsi_cmnd) 1271 if (io_task->scsi_cmnd)
1277 scsi_dma_unmap(io_task->scsi_cmnd); 1272 scsi_dma_unmap(io_task->scsi_cmnd);
@@ -1286,9 +1281,6 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
1286 1281
1287 /* bidi not initially supported */ 1282 /* bidi not initially supported */
1288 if (flags & (ISCSI_FLAG_CMD_UNDERFLOW | ISCSI_FLAG_CMD_OVERFLOW)) { 1283 if (flags & (ISCSI_FLAG_CMD_UNDERFLOW | ISCSI_FLAG_CMD_OVERFLOW)) {
1289 resid = (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) /
1290 32] & SOL_RES_CNT_MASK);
1291
1292 if (!status && (flags & ISCSI_FLAG_CMD_OVERFLOW)) 1284 if (!status && (flags & ISCSI_FLAG_CMD_OVERFLOW))
1293 task->sc->result = DID_ERROR << 16; 1285 task->sc->result = DID_ERROR << 16;
1294 1286
@@ -1310,13 +1302,8 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
1310 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); 1302 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
1311 } 1303 }
1312 1304
1313 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) { 1305 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ)
1314 if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] 1306 conn->rxdata_octets += resid;
1315 & SOL_RES_CNT_MASK)
1316 conn->rxdata_octets += (psol->
1317 dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
1318 & SOL_RES_CNT_MASK);
1319 }
1320unmap: 1307unmap:
1321 scsi_dma_unmap(io_task->scsi_cmnd); 1308 scsi_dma_unmap(io_task->scsi_cmnd);
1322 iscsi_complete_scsi_task(task, exp_cmdsn, max_cmdsn); 1309 iscsi_complete_scsi_task(task, exp_cmdsn, max_cmdsn);
@@ -1324,7 +1311,8 @@ unmap:
1324 1311
1325static void 1312static void
1326be_complete_logout(struct beiscsi_conn *beiscsi_conn, 1313be_complete_logout(struct beiscsi_conn *beiscsi_conn,
1327 struct iscsi_task *task, struct sol_cqe *psol) 1314 struct iscsi_task *task,
1315 struct common_sol_cqe *csol_cqe)
1328{ 1316{
1329 struct iscsi_logout_rsp *hdr; 1317 struct iscsi_logout_rsp *hdr;
1330 struct beiscsi_io_task *io_task = task->dd_data; 1318 struct beiscsi_io_task *io_task = task->dd_data;
@@ -1334,18 +1322,11 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn,
1334 hdr->opcode = ISCSI_OP_LOGOUT_RSP; 1322 hdr->opcode = ISCSI_OP_LOGOUT_RSP;
1335 hdr->t2wait = 5; 1323 hdr->t2wait = 5;
1336 hdr->t2retain = 0; 1324 hdr->t2retain = 0;
1337 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] 1325 hdr->flags = csol_cqe->i_flags;
1338 & SOL_FLAGS_MASK) >> 24) | 0x80; 1326 hdr->response = csol_cqe->i_resp;
1339 hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) / 1327 hdr->exp_cmdsn = csol_cqe->exp_cmdsn;
1340 32] & SOL_RESP_MASK); 1328 hdr->max_cmdsn = (csol_cqe->exp_cmdsn + csol_cqe->cmd_wnd - 1);
1341 hdr->exp_cmdsn = cpu_to_be32(psol-> 1329
1342 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
1343 & SOL_EXP_CMD_SN_MASK);
1344 hdr->max_cmdsn = be32_to_cpu((psol->
1345 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
1346 & SOL_EXP_CMD_SN_MASK) +
1347 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
1348 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
1349 hdr->dlength[0] = 0; 1330 hdr->dlength[0] = 0;
1350 hdr->dlength[1] = 0; 1331 hdr->dlength[1] = 0;
1351 hdr->dlength[2] = 0; 1332 hdr->dlength[2] = 0;
@@ -1356,7 +1337,8 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn,
1356 1337
1357static void 1338static void
1358be_complete_tmf(struct beiscsi_conn *beiscsi_conn, 1339be_complete_tmf(struct beiscsi_conn *beiscsi_conn,
1359 struct iscsi_task *task, struct sol_cqe *psol) 1340 struct iscsi_task *task,
1341 struct common_sol_cqe *csol_cqe)
1360{ 1342{
1361 struct iscsi_tm_rsp *hdr; 1343 struct iscsi_tm_rsp *hdr;
1362 struct iscsi_conn *conn = beiscsi_conn->conn; 1344 struct iscsi_conn *conn = beiscsi_conn->conn;
@@ -1364,16 +1346,12 @@ be_complete_tmf(struct beiscsi_conn *beiscsi_conn,
1364 1346
1365 hdr = (struct iscsi_tm_rsp *)task->hdr; 1347 hdr = (struct iscsi_tm_rsp *)task->hdr;
1366 hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; 1348 hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP;
1367 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] 1349 hdr->flags = csol_cqe->i_flags;
1368 & SOL_FLAGS_MASK) >> 24) | 0x80; 1350 hdr->response = csol_cqe->i_resp;
1369 hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) / 1351 hdr->exp_cmdsn = csol_cqe->exp_cmdsn;
1370 32] & SOL_RESP_MASK); 1352 hdr->max_cmdsn = (csol_cqe->exp_cmdsn +
1371 hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe, 1353 csol_cqe->cmd_wnd - 1);
1372 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK); 1354
1373 hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe,
1374 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) +
1375 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
1376 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
1377 hdr->itt = io_task->libiscsi_itt; 1355 hdr->itt = io_task->libiscsi_itt;
1378 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); 1356 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
1379} 1357}
@@ -1389,15 +1367,24 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
1389 struct beiscsi_io_task *io_task; 1367 struct beiscsi_io_task *io_task;
1390 struct iscsi_conn *conn = beiscsi_conn->conn; 1368 struct iscsi_conn *conn = beiscsi_conn->conn;
1391 struct iscsi_session *session = conn->session; 1369 struct iscsi_session *session = conn->session;
1370 uint16_t wrb_index, cid;
1392 1371
1393 phwi_ctrlr = phba->phwi_ctrlr; 1372 phwi_ctrlr = phba->phwi_ctrlr;
1394 pwrb_context = &phwi_ctrlr->wrb_context[((psol-> 1373 if (chip_skh_r(phba->pcidev)) {
1395 dw[offsetof(struct amap_sol_cqe, cid) / 32] & 1374 wrb_index = AMAP_GET_BITS(struct amap_it_dmsg_cqe_v2,
1396 SOL_CID_MASK) >> 6) - 1375 wrb_idx, psol);
1397 phba->fw_config.iscsi_cid_start]; 1376 cid = AMAP_GET_BITS(struct amap_it_dmsg_cqe_v2,
1398 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> 1377 cid, psol);
1399 dw[offsetof(struct amap_sol_cqe, wrb_index) / 1378 } else {
1400 32] & SOL_WRB_INDEX_MASK) >> 16)]; 1379 wrb_index = AMAP_GET_BITS(struct amap_it_dmsg_cqe,
1380 wrb_idx, psol);
1381 cid = AMAP_GET_BITS(struct amap_it_dmsg_cqe,
1382 cid, psol);
1383 }
1384
1385 pwrb_context = &phwi_ctrlr->wrb_context[
1386 cid - phba->fw_config.iscsi_cid_start];
1387 pwrb_handle = pwrb_context->pwrb_handle_basestd[wrb_index];
1401 task = pwrb_handle->pio_handle; 1388 task = pwrb_handle->pio_handle;
1402 1389
1403 io_task = task->dd_data; 1390 io_task = task->dd_data;
@@ -1411,26 +1398,78 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
1411 1398
1412static void 1399static void
1413be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn, 1400be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn,
1414 struct iscsi_task *task, struct sol_cqe *psol) 1401 struct iscsi_task *task,
1402 struct common_sol_cqe *csol_cqe)
1415{ 1403{
1416 struct iscsi_nopin *hdr; 1404 struct iscsi_nopin *hdr;
1417 struct iscsi_conn *conn = beiscsi_conn->conn; 1405 struct iscsi_conn *conn = beiscsi_conn->conn;
1418 struct beiscsi_io_task *io_task = task->dd_data; 1406 struct beiscsi_io_task *io_task = task->dd_data;
1419 1407
1420 hdr = (struct iscsi_nopin *)task->hdr; 1408 hdr = (struct iscsi_nopin *)task->hdr;
1421 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] 1409 hdr->flags = csol_cqe->i_flags;
1422 & SOL_FLAGS_MASK) >> 24) | 0x80; 1410 hdr->exp_cmdsn = cpu_to_be32(csol_cqe->exp_cmdsn);
1423 hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe, 1411 hdr->max_cmdsn = be32_to_cpu(hdr->exp_cmdsn +
1424 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK); 1412 csol_cqe->cmd_wnd - 1);
1425 hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe, 1413
1426 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) +
1427 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
1428 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
1429 hdr->opcode = ISCSI_OP_NOOP_IN; 1414 hdr->opcode = ISCSI_OP_NOOP_IN;
1430 hdr->itt = io_task->libiscsi_itt; 1415 hdr->itt = io_task->libiscsi_itt;
1431 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); 1416 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
1432} 1417}
1433 1418
1419static void adapter_get_sol_cqe(struct beiscsi_hba *phba,
1420 struct sol_cqe *psol,
1421 struct common_sol_cqe *csol_cqe)
1422{
1423 if (chip_skh_r(phba->pcidev)) {
1424 csol_cqe->exp_cmdsn = AMAP_GET_BITS(struct amap_sol_cqe_v2,
1425 i_exp_cmd_sn, psol);
1426 csol_cqe->res_cnt = AMAP_GET_BITS(struct amap_sol_cqe_v2,
1427 i_res_cnt, psol);
1428 csol_cqe->wrb_index = AMAP_GET_BITS(struct amap_sol_cqe_v2,
1429 wrb_index, psol);
1430 csol_cqe->cid = AMAP_GET_BITS(struct amap_sol_cqe_v2,
1431 cid, psol);
1432 csol_cqe->hw_sts = AMAP_GET_BITS(struct amap_sol_cqe_v2,
1433 hw_sts, psol);
1434 csol_cqe->cmd_wnd = AMAP_GET_BITS(struct amap_sol_cqe,
1435 i_cmd_wnd, psol);
1436 if (AMAP_GET_BITS(struct amap_sol_cqe_v2,
1437 cmd_cmpl, psol))
1438 csol_cqe->i_sts = AMAP_GET_BITS(struct amap_sol_cqe_v2,
1439 i_sts, psol);
1440 else
1441 csol_cqe->i_resp = AMAP_GET_BITS(struct amap_sol_cqe_v2,
1442 i_sts, psol);
1443 if (AMAP_GET_BITS(struct amap_sol_cqe_v2,
1444 u, psol))
1445 csol_cqe->i_flags = ISCSI_FLAG_CMD_UNDERFLOW;
1446
1447 if (AMAP_GET_BITS(struct amap_sol_cqe_v2,
1448 o, psol))
1449 csol_cqe->i_flags |= ISCSI_FLAG_CMD_OVERFLOW;
1450 } else {
1451 csol_cqe->exp_cmdsn = AMAP_GET_BITS(struct amap_sol_cqe,
1452 i_exp_cmd_sn, psol);
1453 csol_cqe->res_cnt = AMAP_GET_BITS(struct amap_sol_cqe,
1454 i_res_cnt, psol);
1455 csol_cqe->cmd_wnd = AMAP_GET_BITS(struct amap_sol_cqe,
1456 i_cmd_wnd, psol);
1457 csol_cqe->wrb_index = AMAP_GET_BITS(struct amap_sol_cqe,
1458 wrb_index, psol);
1459 csol_cqe->cid = AMAP_GET_BITS(struct amap_sol_cqe,
1460 cid, psol);
1461 csol_cqe->hw_sts = AMAP_GET_BITS(struct amap_sol_cqe,
1462 hw_sts, psol);
1463 csol_cqe->i_resp = AMAP_GET_BITS(struct amap_sol_cqe,
1464 i_resp, psol);
1465 csol_cqe->i_sts = AMAP_GET_BITS(struct amap_sol_cqe,
1466 i_sts, psol);
1467 csol_cqe->i_flags = AMAP_GET_BITS(struct amap_sol_cqe,
1468 i_flags, psol);
1469 }
1470}
1471
1472
1434static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, 1473static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
1435 struct beiscsi_hba *phba, struct sol_cqe *psol) 1474 struct beiscsi_hba *phba, struct sol_cqe *psol)
1436{ 1475{
@@ -1442,19 +1481,22 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
1442 unsigned int type; 1481 unsigned int type;
1443 struct iscsi_conn *conn = beiscsi_conn->conn; 1482 struct iscsi_conn *conn = beiscsi_conn->conn;
1444 struct iscsi_session *session = conn->session; 1483 struct iscsi_session *session = conn->session;
1484 struct common_sol_cqe csol_cqe = {0};
1445 1485
1446 phwi_ctrlr = phba->phwi_ctrlr; 1486 phwi_ctrlr = phba->phwi_ctrlr;
1447 pwrb_context = &phwi_ctrlr->wrb_context[((psol->dw[offsetof 1487
1448 (struct amap_sol_cqe, cid) / 32] 1488 /* Copy the elements to a common structure */
1449 & SOL_CID_MASK) >> 6) - 1489 adapter_get_sol_cqe(phba, psol, &csol_cqe);
1450 phba->fw_config.iscsi_cid_start]; 1490
1451 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> 1491 pwrb_context = &phwi_ctrlr->wrb_context[
1452 dw[offsetof(struct amap_sol_cqe, wrb_index) / 1492 csol_cqe.cid - phba->fw_config.iscsi_cid_start];
1453 32] & SOL_WRB_INDEX_MASK) >> 16)]; 1493
1494 pwrb_handle = pwrb_context->pwrb_handle_basestd[
1495 csol_cqe.wrb_index];
1496
1454 task = pwrb_handle->pio_handle; 1497 task = pwrb_handle->pio_handle;
1455 pwrb = pwrb_handle->pwrb; 1498 pwrb = pwrb_handle->pwrb;
1456 type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] & 1499 type = ((struct beiscsi_io_task *)task->dd_data)->wrb_type;
1457 WRB_TYPE_MASK) >> 28;
1458 1500
1459 spin_lock_bh(&session->lock); 1501 spin_lock_bh(&session->lock);
1460 switch (type) { 1502 switch (type) {
@@ -1462,17 +1504,16 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
1462 case HWH_TYPE_IO_RD: 1504 case HWH_TYPE_IO_RD:
1463 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == 1505 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
1464 ISCSI_OP_NOOP_OUT) 1506 ISCSI_OP_NOOP_OUT)
1465 be_complete_nopin_resp(beiscsi_conn, task, psol); 1507 be_complete_nopin_resp(beiscsi_conn, task, &csol_cqe);
1466 else 1508 else
1467 be_complete_io(beiscsi_conn, task, psol); 1509 be_complete_io(beiscsi_conn, task, &csol_cqe);
1468 break; 1510 break;
1469 1511
1470 case HWH_TYPE_LOGOUT: 1512 case HWH_TYPE_LOGOUT:
1471 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) 1513 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
1472 be_complete_logout(beiscsi_conn, task, psol); 1514 be_complete_logout(beiscsi_conn, task, &csol_cqe);
1473 else 1515 else
1474 be_complete_tmf(beiscsi_conn, task, psol); 1516 be_complete_tmf(beiscsi_conn, task, &csol_cqe);
1475
1476 break; 1517 break;
1477 1518
1478 case HWH_TYPE_LOGIN: 1519 case HWH_TYPE_LOGIN:
@@ -1483,7 +1524,7 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
1483 break; 1524 break;
1484 1525
1485 case HWH_TYPE_NOP: 1526 case HWH_TYPE_NOP:
1486 be_complete_nopin_resp(beiscsi_conn, task, psol); 1527 be_complete_nopin_resp(beiscsi_conn, task, &csol_cqe);
1487 break; 1528 break;
1488 1529
1489 default: 1530 default:
@@ -1491,10 +1532,8 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
1491 BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO, 1532 BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
1492 "BM_%d : In hwi_complete_cmd, unknown type = %d" 1533 "BM_%d : In hwi_complete_cmd, unknown type = %d"
1493 "wrb_index 0x%x CID 0x%x\n", type, 1534 "wrb_index 0x%x CID 0x%x\n", type,
1494 ((psol->dw[offsetof(struct amap_iscsi_wrb, 1535 csol_cqe.wrb_index,
1495 type) / 32] & SOL_WRB_INDEX_MASK) >> 16), 1536 csol_cqe.cid);
1496 ((psol->dw[offsetof(struct amap_sol_cqe,
1497 cid) / 32] & SOL_CID_MASK) >> 6));
1498 break; 1537 break;
1499 } 1538 }
1500 1539
@@ -1522,13 +1561,26 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
1522 struct list_head *pbusy_list; 1561 struct list_head *pbusy_list;
1523 struct async_pdu_handle *pasync_handle = NULL; 1562 struct async_pdu_handle *pasync_handle = NULL;
1524 unsigned char is_header = 0; 1563 unsigned char is_header = 0;
1564 unsigned int index, dpl;
1565
1566 if (chip_skh_r(phba->pcidev)) {
1567 dpl = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe_v2,
1568 dpl, pdpdu_cqe);
1569 index = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe_v2,
1570 index, pdpdu_cqe);
1571 } else {
1572 dpl = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe,
1573 dpl, pdpdu_cqe);
1574 index = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe,
1575 index, pdpdu_cqe);
1576 }
1525 1577
1526 phys_addr.u.a32.address_lo = 1578 phys_addr.u.a32.address_lo =
1527 pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, db_addr_lo) / 32] - 1579 (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
1528 ((pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32] 1580 db_addr_lo) / 32] - dpl);
1529 & PDUCQE_DPL_MASK) >> 16);
1530 phys_addr.u.a32.address_hi = 1581 phys_addr.u.a32.address_hi =
1531 pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, db_addr_hi) / 32]; 1582 pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
1583 db_addr_hi) / 32];
1532 1584
1533 phys_addr.u.a64.address = 1585 phys_addr.u.a64.address =
1534 *((unsigned long long *)(&phys_addr.u.a64.address)); 1586 *((unsigned long long *)(&phys_addr.u.a64.address));
@@ -1538,14 +1590,12 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
1538 case UNSOL_HDR_NOTIFY: 1590 case UNSOL_HDR_NOTIFY:
1539 is_header = 1; 1591 is_header = 1;
1540 1592
1541 pbusy_list = hwi_get_async_busy_list(pasync_ctx, 1, 1593 pbusy_list = hwi_get_async_busy_list(pasync_ctx,
1542 (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, 1594 is_header, index);
1543 index) / 32] & PDUCQE_INDEX_MASK));
1544 break; 1595 break;
1545 case UNSOL_DATA_NOTIFY: 1596 case UNSOL_DATA_NOTIFY:
1546 pbusy_list = hwi_get_async_busy_list(pasync_ctx, 0, (pdpdu_cqe-> 1597 pbusy_list = hwi_get_async_busy_list(pasync_ctx,
1547 dw[offsetof(struct amap_i_t_dpdu_cqe, 1598 is_header, index);
1548 index) / 32] & PDUCQE_INDEX_MASK));
1549 break; 1599 break;
1550 default: 1600 default:
1551 pbusy_list = NULL; 1601 pbusy_list = NULL;
@@ -1568,12 +1618,9 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
1568 pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid - 1618 pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid -
1569 phba->fw_config.iscsi_cid_start; 1619 phba->fw_config.iscsi_cid_start;
1570 pasync_handle->is_header = is_header; 1620 pasync_handle->is_header = is_header;
1571 pasync_handle->buffer_len = ((pdpdu_cqe-> 1621 pasync_handle->buffer_len = dpl;
1572 dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32] 1622 *pcq_index = index;
1573 & PDUCQE_DPL_MASK) >> 16);
1574 1623
1575 *pcq_index = (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
1576 index) / 32] & PDUCQE_INDEX_MASK);
1577 return pasync_handle; 1624 return pasync_handle;
1578} 1625}
1579 1626
@@ -1979,12 +2026,24 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1979 CQE_VALID_MASK) { 2026 CQE_VALID_MASK) {
1980 be_dws_le_to_cpu(sol, sizeof(struct sol_cqe)); 2027 be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));
1981 2028
1982 cid = ((sol->dw[offsetof(struct amap_sol_cqe, cid)/32] & 2029 code = (sol->dw[offsetof(struct amap_sol_cqe, code) /
1983 CQE_CID_MASK) >> 6); 2030 32] & CQE_CODE_MASK);
1984 code = (sol->dw[offsetof(struct amap_sol_cqe, code)/32] & 2031
1985 CQE_CODE_MASK); 2032 /* Get the CID */
1986 ep = phba->ep_array[cid - phba->fw_config.iscsi_cid_start]; 2033 if (chip_skh_r(phba->pcidev)) {
2034 if ((code == DRIVERMSG_NOTIFY) ||
2035 (code == UNSOL_HDR_NOTIFY) ||
2036 (code == UNSOL_DATA_NOTIFY))
2037 cid = AMAP_GET_BITS(
2038 struct amap_i_t_dpdu_cqe_v2,
2039 cid, sol);
2040 else
2041 cid = AMAP_GET_BITS(struct amap_sol_cqe_v2,
2042 cid, sol);
2043 } else
2044 cid = AMAP_GET_BITS(struct amap_sol_cqe, cid, sol);
1987 2045
2046 ep = phba->ep_array[cid - phba->fw_config.iscsi_cid_start];
1988 beiscsi_ep = ep->dd_data; 2047 beiscsi_ep = ep->dd_data;
1989 beiscsi_conn = beiscsi_ep->conn; 2048 beiscsi_conn = beiscsi_ep->conn;
1990 2049
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 0e730d1cd1af..2b722c873455 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -587,6 +587,20 @@ struct amap_i_t_dpdu_cqe {
587 u8 valid; 587 u8 valid;
588} __packed; 588} __packed;
589 589
590struct amap_i_t_dpdu_cqe_v2 {
591 u8 db_addr_hi[32]; /* DWORD 0 */
592 u8 db_addr_lo[32]; /* DWORD 1 */
593 u8 code[6]; /* DWORD 2 */
594 u8 num_cons; /* DWORD 2*/
595 u8 rsvd0[8]; /* DWORD 2 */
596 u8 dpl[17]; /* DWORD 2 */
597 u8 index[16]; /* DWORD 3 */
598 u8 cid[13]; /* DWORD 3 */
599 u8 rsvd1; /* DWORD 3 */
600 u8 final; /* DWORD 3 */
601 u8 valid; /* DWORD 3 */
602} __packed;
603
590#define CQE_VALID_MASK 0x80000000 604#define CQE_VALID_MASK 0x80000000
591#define CQE_CODE_MASK 0x0000003F 605#define CQE_CODE_MASK 0x0000003F
592#define CQE_CID_MASK 0x0000FFC0 606#define CQE_CID_MASK 0x0000FFC0