Commit 7313326125c8da52a10780b5af3b290fa9498dcb
Committed by
James Bottomley
1 parent
acb9693cb0
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
[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>
Showing 3 changed files with 230 additions and 104 deletions Side-by-side Diff
drivers/scsi/be2iscsi/be_cmds.h
... | ... | @@ -826,6 +826,59 @@ |
826 | 826 | u8 valid; /* dword 3 */ |
827 | 827 | } __packed; |
828 | 828 | |
829 | +struct 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 | + | |
846 | +struct 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 ***/ | |
860 | +struct 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 | + | |
871 | +struct 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 | /** |
drivers/scsi/be2iscsi/be_main.c
... | ... | @@ -1248,7 +1248,8 @@ |
1248 | 1248 | |
1249 | 1249 | static void |
1250 | 1250 | be_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 | 1254 | struct beiscsi_io_task *io_task = task->dd_data; |
1254 | 1255 | struct be_status_bhs *sts_bhs = |
... | ... | @@ -1258,20 +1259,14 @@ |
1258 | 1259 | u32 resid = 0, exp_cmdsn, max_cmdsn; |
1259 | 1260 | u8 rsp, status, flags; |
1260 | 1261 | |
1261 | - exp_cmdsn = (psol-> | |
1262 | - dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32] | |
1263 | - & SOL_EXP_CMD_SN_MASK); | |
1264 | - max_cmdsn = ((psol-> | |
1265 | - dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32] | |
1266 | - & SOL_EXP_CMD_SN_MASK) + | |
1267 | - ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) | |
1268 | - / 32] & SOL_CMD_WND_MASK) >> 24) - 1); | |
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; | |
1262 | + exp_cmdsn = csol_cqe->exp_cmdsn; | |
1263 | + max_cmdsn = (csol_cqe->exp_cmdsn + | |
1264 | + csol_cqe->cmd_wnd - 1); | |
1265 | + rsp = csol_cqe->i_resp; | |
1266 | + status = csol_cqe->i_sts; | |
1267 | + flags = csol_cqe->i_flags; | |
1268 | + resid = csol_cqe->res_cnt; | |
1269 | + | |
1275 | 1270 | if (!task->sc) { |
1276 | 1271 | if (io_task->scsi_cmnd) |
1277 | 1272 | scsi_dma_unmap(io_task->scsi_cmnd); |
... | ... | @@ -1286,9 +1281,6 @@ |
1286 | 1281 | |
1287 | 1282 | /* bidi not initially supported */ |
1288 | 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 | 1284 | if (!status && (flags & ISCSI_FLAG_CMD_OVERFLOW)) |
1293 | 1285 | task->sc->result = DID_ERROR << 16; |
1294 | 1286 | |
... | ... | @@ -1310,13 +1302,8 @@ |
1310 | 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) { | |
1314 | - if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] | |
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 | - } | |
1305 | + if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) | |
1306 | + conn->rxdata_octets += resid; | |
1320 | 1307 | unmap: |
1321 | 1308 | scsi_dma_unmap(io_task->scsi_cmnd); |
1322 | 1309 | iscsi_complete_scsi_task(task, exp_cmdsn, max_cmdsn); |
... | ... | @@ -1324,7 +1311,8 @@ |
1324 | 1311 | |
1325 | 1312 | static void |
1326 | 1313 | be_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 | 1317 | struct iscsi_logout_rsp *hdr; |
1330 | 1318 | struct beiscsi_io_task *io_task = task->dd_data; |
... | ... | @@ -1334,18 +1322,11 @@ |
1334 | 1322 | hdr->opcode = ISCSI_OP_LOGOUT_RSP; |
1335 | 1323 | hdr->t2wait = 5; |
1336 | 1324 | hdr->t2retain = 0; |
1337 | - hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] | |
1338 | - & SOL_FLAGS_MASK) >> 24) | 0x80; | |
1339 | - hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) / | |
1340 | - 32] & SOL_RESP_MASK); | |
1341 | - hdr->exp_cmdsn = cpu_to_be32(psol-> | |
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); | |
1325 | + hdr->flags = csol_cqe->i_flags; | |
1326 | + hdr->response = csol_cqe->i_resp; | |
1327 | + hdr->exp_cmdsn = csol_cqe->exp_cmdsn; | |
1328 | + hdr->max_cmdsn = (csol_cqe->exp_cmdsn + csol_cqe->cmd_wnd - 1); | |
1329 | + | |
1349 | 1330 | hdr->dlength[0] = 0; |
1350 | 1331 | hdr->dlength[1] = 0; |
1351 | 1332 | hdr->dlength[2] = 0; |
... | ... | @@ -1356,7 +1337,8 @@ |
1356 | 1337 | |
1357 | 1338 | static void |
1358 | 1339 | be_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 | 1343 | struct iscsi_tm_rsp *hdr; |
1362 | 1344 | struct iscsi_conn *conn = beiscsi_conn->conn; |
... | ... | @@ -1364,16 +1346,12 @@ |
1364 | 1346 | |
1365 | 1347 | hdr = (struct iscsi_tm_rsp *)task->hdr; |
1366 | 1348 | hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; |
1367 | - hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] | |
1368 | - & SOL_FLAGS_MASK) >> 24) | 0x80; | |
1369 | - hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) / | |
1370 | - 32] & SOL_RESP_MASK); | |
1371 | - hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe, | |
1372 | - i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK); | |
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); | |
1349 | + hdr->flags = csol_cqe->i_flags; | |
1350 | + hdr->response = csol_cqe->i_resp; | |
1351 | + hdr->exp_cmdsn = csol_cqe->exp_cmdsn; | |
1352 | + hdr->max_cmdsn = (csol_cqe->exp_cmdsn + | |
1353 | + csol_cqe->cmd_wnd - 1); | |
1354 | + | |
1377 | 1355 | hdr->itt = io_task->libiscsi_itt; |
1378 | 1356 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); |
1379 | 1357 | } |
1380 | 1358 | |
... | ... | @@ -1389,15 +1367,24 @@ |
1389 | 1367 | struct beiscsi_io_task *io_task; |
1390 | 1368 | struct iscsi_conn *conn = beiscsi_conn->conn; |
1391 | 1369 | struct iscsi_session *session = conn->session; |
1370 | + uint16_t wrb_index, cid; | |
1392 | 1371 | |
1393 | 1372 | phwi_ctrlr = phba->phwi_ctrlr; |
1394 | - pwrb_context = &phwi_ctrlr->wrb_context[((psol-> | |
1395 | - dw[offsetof(struct amap_sol_cqe, cid) / 32] & | |
1396 | - SOL_CID_MASK) >> 6) - | |
1397 | - phba->fw_config.iscsi_cid_start]; | |
1398 | - pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | |
1399 | - dw[offsetof(struct amap_sol_cqe, wrb_index) / | |
1400 | - 32] & SOL_WRB_INDEX_MASK) >> 16)]; | |
1373 | + if (chip_skh_r(phba->pcidev)) { | |
1374 | + wrb_index = AMAP_GET_BITS(struct amap_it_dmsg_cqe_v2, | |
1375 | + wrb_idx, psol); | |
1376 | + cid = AMAP_GET_BITS(struct amap_it_dmsg_cqe_v2, | |
1377 | + cid, psol); | |
1378 | + } else { | |
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 | 1388 | task = pwrb_handle->pio_handle; |
1402 | 1389 | |
1403 | 1390 | io_task = task->dd_data; |
1404 | 1391 | |
1405 | 1392 | |
... | ... | @@ -1411,26 +1398,78 @@ |
1411 | 1398 | |
1412 | 1399 | static void |
1413 | 1400 | be_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 | 1404 | struct iscsi_nopin *hdr; |
1417 | 1405 | struct iscsi_conn *conn = beiscsi_conn->conn; |
1418 | 1406 | struct beiscsi_io_task *io_task = task->dd_data; |
1419 | 1407 | |
1420 | 1408 | hdr = (struct iscsi_nopin *)task->hdr; |
1421 | - hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] | |
1422 | - & SOL_FLAGS_MASK) >> 24) | 0x80; | |
1423 | - hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe, | |
1424 | - i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK); | |
1425 | - hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe, | |
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); | |
1409 | + hdr->flags = csol_cqe->i_flags; | |
1410 | + hdr->exp_cmdsn = cpu_to_be32(csol_cqe->exp_cmdsn); | |
1411 | + hdr->max_cmdsn = be32_to_cpu(hdr->exp_cmdsn + | |
1412 | + csol_cqe->cmd_wnd - 1); | |
1413 | + | |
1429 | 1414 | hdr->opcode = ISCSI_OP_NOOP_IN; |
1430 | 1415 | hdr->itt = io_task->libiscsi_itt; |
1431 | 1416 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); |
1432 | 1417 | } |
1433 | 1418 | |
1419 | +static 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 | + | |
1434 | 1473 | static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, |
1435 | 1474 | struct beiscsi_hba *phba, struct sol_cqe *psol) |
1436 | 1475 | { |
1437 | 1476 | |
1438 | 1477 | |
... | ... | @@ -1442,19 +1481,22 @@ |
1442 | 1481 | unsigned int type; |
1443 | 1482 | struct iscsi_conn *conn = beiscsi_conn->conn; |
1444 | 1483 | struct iscsi_session *session = conn->session; |
1484 | + struct common_sol_cqe csol_cqe = {0}; | |
1445 | 1485 | |
1446 | 1486 | phwi_ctrlr = phba->phwi_ctrlr; |
1447 | - pwrb_context = &phwi_ctrlr->wrb_context[((psol->dw[offsetof | |
1448 | - (struct amap_sol_cqe, cid) / 32] | |
1449 | - & SOL_CID_MASK) >> 6) - | |
1450 | - phba->fw_config.iscsi_cid_start]; | |
1451 | - pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | |
1452 | - dw[offsetof(struct amap_sol_cqe, wrb_index) / | |
1453 | - 32] & SOL_WRB_INDEX_MASK) >> 16)]; | |
1487 | + | |
1488 | + /* Copy the elements to a common structure */ | |
1489 | + adapter_get_sol_cqe(phba, psol, &csol_cqe); | |
1490 | + | |
1491 | + pwrb_context = &phwi_ctrlr->wrb_context[ | |
1492 | + csol_cqe.cid - phba->fw_config.iscsi_cid_start]; | |
1493 | + | |
1494 | + pwrb_handle = pwrb_context->pwrb_handle_basestd[ | |
1495 | + csol_cqe.wrb_index]; | |
1496 | + | |
1454 | 1497 | task = pwrb_handle->pio_handle; |
1455 | 1498 | pwrb = pwrb_handle->pwrb; |
1456 | - type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] & | |
1457 | - WRB_TYPE_MASK) >> 28; | |
1499 | + type = ((struct beiscsi_io_task *)task->dd_data)->wrb_type; | |
1458 | 1500 | |
1459 | 1501 | spin_lock_bh(&session->lock); |
1460 | 1502 | switch (type) { |
1461 | 1503 | |
1462 | 1504 | |
1463 | 1505 | |
... | ... | @@ -1462,17 +1504,16 @@ |
1462 | 1504 | case HWH_TYPE_IO_RD: |
1463 | 1505 | if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == |
1464 | 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 | 1508 | else |
1467 | - be_complete_io(beiscsi_conn, task, psol); | |
1509 | + be_complete_io(beiscsi_conn, task, &csol_cqe); | |
1468 | 1510 | break; |
1469 | 1511 | |
1470 | 1512 | case HWH_TYPE_LOGOUT: |
1471 | 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 | 1515 | else |
1474 | - be_complete_tmf(beiscsi_conn, task, psol); | |
1475 | - | |
1516 | + be_complete_tmf(beiscsi_conn, task, &csol_cqe); | |
1476 | 1517 | break; |
1477 | 1518 | |
1478 | 1519 | case HWH_TYPE_LOGIN: |
... | ... | @@ -1483,7 +1524,7 @@ |
1483 | 1524 | break; |
1484 | 1525 | |
1485 | 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 | 1528 | break; |
1488 | 1529 | |
1489 | 1530 | default: |
... | ... | @@ -1491,10 +1532,8 @@ |
1491 | 1532 | BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO, |
1492 | 1533 | "BM_%d : In hwi_complete_cmd, unknown type = %d" |
1493 | 1534 | "wrb_index 0x%x CID 0x%x\n", type, |
1494 | - ((psol->dw[offsetof(struct amap_iscsi_wrb, | |
1495 | - type) / 32] & SOL_WRB_INDEX_MASK) >> 16), | |
1496 | - ((psol->dw[offsetof(struct amap_sol_cqe, | |
1497 | - cid) / 32] & SOL_CID_MASK) >> 6)); | |
1535 | + csol_cqe.wrb_index, | |
1536 | + csol_cqe.cid); | |
1498 | 1537 | break; |
1499 | 1538 | } |
1500 | 1539 | |
1501 | 1540 | |
1502 | 1541 | |
1503 | 1542 | |
... | ... | @@ -1522,13 +1561,26 @@ |
1522 | 1561 | struct list_head *pbusy_list; |
1523 | 1562 | struct async_pdu_handle *pasync_handle = NULL; |
1524 | 1563 | unsigned char is_header = 0; |
1564 | + unsigned int index, dpl; | |
1525 | 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 | + } | |
1577 | + | |
1526 | 1578 | phys_addr.u.a32.address_lo = |
1527 | - pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, db_addr_lo) / 32] - | |
1528 | - ((pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32] | |
1529 | - & PDUCQE_DPL_MASK) >> 16); | |
1579 | + (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, | |
1580 | + db_addr_lo) / 32] - dpl); | |
1530 | 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 | 1585 | phys_addr.u.a64.address = |
1534 | 1586 | *((unsigned long long *)(&phys_addr.u.a64.address)); |
1535 | 1587 | |
... | ... | @@ -1538,14 +1590,12 @@ |
1538 | 1590 | case UNSOL_HDR_NOTIFY: |
1539 | 1591 | is_header = 1; |
1540 | 1592 | |
1541 | - pbusy_list = hwi_get_async_busy_list(pasync_ctx, 1, | |
1542 | - (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, | |
1543 | - index) / 32] & PDUCQE_INDEX_MASK)); | |
1593 | + pbusy_list = hwi_get_async_busy_list(pasync_ctx, | |
1594 | + is_header, index); | |
1544 | 1595 | break; |
1545 | 1596 | case UNSOL_DATA_NOTIFY: |
1546 | - pbusy_list = hwi_get_async_busy_list(pasync_ctx, 0, (pdpdu_cqe-> | |
1547 | - dw[offsetof(struct amap_i_t_dpdu_cqe, | |
1548 | - index) / 32] & PDUCQE_INDEX_MASK)); | |
1597 | + pbusy_list = hwi_get_async_busy_list(pasync_ctx, | |
1598 | + is_header, index); | |
1549 | 1599 | break; |
1550 | 1600 | default: |
1551 | 1601 | pbusy_list = NULL; |
1552 | 1602 | |
... | ... | @@ -1568,12 +1618,9 @@ |
1568 | 1618 | pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid - |
1569 | 1619 | phba->fw_config.iscsi_cid_start; |
1570 | 1620 | pasync_handle->is_header = is_header; |
1571 | - pasync_handle->buffer_len = ((pdpdu_cqe-> | |
1572 | - dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32] | |
1573 | - & PDUCQE_DPL_MASK) >> 16); | |
1621 | + pasync_handle->buffer_len = dpl; | |
1622 | + *pcq_index = index; | |
1574 | 1623 | |
1575 | - *pcq_index = (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, | |
1576 | - index) / 32] & PDUCQE_INDEX_MASK); | |
1577 | 1624 | return pasync_handle; |
1578 | 1625 | } |
1579 | 1626 | |
1580 | 1627 | |
... | ... | @@ -1979,12 +2026,24 @@ |
1979 | 2026 | CQE_VALID_MASK) { |
1980 | 2027 | be_dws_le_to_cpu(sol, sizeof(struct sol_cqe)); |
1981 | 2028 | |
1982 | - cid = ((sol->dw[offsetof(struct amap_sol_cqe, cid)/32] & | |
1983 | - CQE_CID_MASK) >> 6); | |
1984 | - code = (sol->dw[offsetof(struct amap_sol_cqe, code)/32] & | |
1985 | - CQE_CODE_MASK); | |
1986 | - ep = phba->ep_array[cid - phba->fw_config.iscsi_cid_start]; | |
2029 | + code = (sol->dw[offsetof(struct amap_sol_cqe, code) / | |
2030 | + 32] & CQE_CODE_MASK); | |
1987 | 2031 | |
2032 | + /* Get the CID */ | |
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); | |
2045 | + | |
2046 | + ep = phba->ep_array[cid - phba->fw_config.iscsi_cid_start]; | |
1988 | 2047 | beiscsi_ep = ep->dd_data; |
1989 | 2048 | beiscsi_conn = beiscsi_ep->conn; |
1990 | 2049 |
drivers/scsi/be2iscsi/be_main.h
... | ... | @@ -587,6 +587,20 @@ |
587 | 587 | u8 valid; |
588 | 588 | } __packed; |
589 | 589 | |
590 | +struct 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 | 604 | #define CQE_VALID_MASK 0x80000000 |
591 | 605 | #define CQE_CODE_MASK 0x0000003F |
592 | 606 | #define CQE_CID_MASK 0x0000FFC0 |