diff options
author | John Soni Jose <sony.john-n@emulex.com> | 2012-10-19 19:14:49 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-11-26 23:59:40 -0500 |
commit | 7313326125c8da52a10780b5af3b290fa9498dcb (patch) | |
tree | c5a4237364af2a9f12f558e4dc20c59b8006ede1 /drivers/scsi/be2iscsi | |
parent | acb9693cb007e126fd313cb696dfbf5c214514cd (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.h | 53 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 267 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 14 |
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 | ||
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 | /** |
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 | ||
1249 | static void | 1249 | static void |
1250 | be_complete_io(struct beiscsi_conn *beiscsi_conn, | 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 | 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 | } | ||
1320 | unmap: | 1307 | unmap: |
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 | ||
1325 | static void | 1312 | static void |
1326 | be_complete_logout(struct beiscsi_conn *beiscsi_conn, | 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 | 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 | ||
1357 | static void | 1338 | static void |
1358 | be_complete_tmf(struct beiscsi_conn *beiscsi_conn, | 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 | 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 | ||
1412 | static void | 1399 | static void |
1413 | be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn, | 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 | 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 | ||
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 | static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, | 1473 | static 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 | ||
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 | #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 |