diff options
author | Jayamohan Kallickal <jayamohank@serverengines.com> | 2009-10-23 02:23:49 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:00:39 -0500 |
commit | 35e6601903fc41e48e9b6722a49cc5acc7065c51 (patch) | |
tree | 36a2d144643c6c2aee9d5e4e6590f26c54c6a486 /drivers/scsi/be2iscsi | |
parent | bfead3b2cb4607c71831423c3ee97d22cd0c9dcb (diff) |
[SCSI] be2iscsi: Adding Ring Mode Wrb's V3
This patch adds support for ring based wrbs
Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 6 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 209 |
3 files changed, 169 insertions, 48 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 10f8fe7a38d2..698a527d6cca 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -125,7 +125,7 @@ static void beiscsi_cq_notify(struct beiscsi_hba *phba, u16 qid, bool arm, | |||
125 | } | 125 | } |
126 | 126 | ||
127 | 127 | ||
128 | int be_process_mcc(struct beiscsi_hba *phba) | 128 | int beiscsi_process_mcc(struct beiscsi_hba *phba) |
129 | { | 129 | { |
130 | struct be_mcc_compl *compl; | 130 | struct be_mcc_compl *compl; |
131 | int num = 0, status = 0; | 131 | int num = 0, status = 0; |
@@ -161,7 +161,7 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba) | |||
161 | #define mcc_timeout 120000 /* 5s timeout */ | 161 | #define mcc_timeout 120000 /* 5s timeout */ |
162 | int i, status; | 162 | int i, status; |
163 | for (i = 0; i < mcc_timeout; i++) { | 163 | for (i = 0; i < mcc_timeout; i++) { |
164 | status = be_process_mcc(phba); | 164 | status = beiscsi_process_mcc(phba); |
165 | if (status) | 165 | if (status) |
166 | return status; | 166 | return status; |
167 | 167 | ||
@@ -504,7 +504,7 @@ static u32 be_encoded_q_len(int q_len) | |||
504 | return len_encoded; | 504 | return len_encoded; |
505 | } | 505 | } |
506 | 506 | ||
507 | int be_cmd_mccq_create(struct beiscsi_hba *phba, | 507 | int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba, |
508 | struct be_queue_info *mccq, | 508 | struct be_queue_info *mccq, |
509 | struct be_queue_info *cq) | 509 | struct be_queue_info *cq) |
510 | { | 510 | { |
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 76fe1f9dd4cb..5de8acb924cb 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h | |||
@@ -418,7 +418,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, | |||
418 | 418 | ||
419 | int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, | 419 | int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, |
420 | int type); | 420 | int type); |
421 | int be_cmd_mccq_create(struct beiscsi_hba *phba, | 421 | int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba, |
422 | struct be_queue_info *mccq, | 422 | struct be_queue_info *mccq, |
423 | struct be_queue_info *cq); | 423 | struct be_queue_info *cq); |
424 | 424 | ||
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 2c3e99eeff82..d15df07ba783 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -40,6 +40,7 @@ | |||
40 | static unsigned int be_iopoll_budget = 10; | 40 | static unsigned int be_iopoll_budget = 10; |
41 | static unsigned int be_max_phys_size = 64; | 41 | static unsigned int be_max_phys_size = 64; |
42 | static unsigned int enable_msix = 1; | 42 | static unsigned int enable_msix = 1; |
43 | static unsigned int ring_mode; | ||
43 | 44 | ||
44 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); | 45 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); |
45 | MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); | 46 | MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); |
@@ -670,8 +671,9 @@ static void | |||
670 | free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context, | 671 | free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context, |
671 | struct wrb_handle *pwrb_handle) | 672 | struct wrb_handle *pwrb_handle) |
672 | { | 673 | { |
673 | 674 | if (!ring_mode) | |
674 | pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle; | 675 | pwrb_context->pwrb_handle_base[pwrb_context->free_index] = |
676 | pwrb_handle; | ||
675 | pwrb_context->wrb_handles_available++; | 677 | pwrb_context->wrb_handles_available++; |
676 | if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1)) | 678 | if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1)) |
677 | pwrb_context->free_index = 0; | 679 | pwrb_context->free_index = 0; |
@@ -857,6 +859,7 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, | |||
857 | { | 859 | { |
858 | struct hwi_wrb_context *pwrb_context; | 860 | struct hwi_wrb_context *pwrb_context; |
859 | struct wrb_handle *pwrb_handle = NULL; | 861 | struct wrb_handle *pwrb_handle = NULL; |
862 | struct sgl_handle *psgl_handle = NULL; | ||
860 | struct hwi_controller *phwi_ctrlr; | 863 | struct hwi_controller *phwi_ctrlr; |
861 | struct iscsi_task *task; | 864 | struct iscsi_task *task; |
862 | struct beiscsi_io_task *io_task; | 865 | struct beiscsi_io_task *io_task; |
@@ -864,13 +867,23 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, | |||
864 | struct iscsi_session *session = conn->session; | 867 | struct iscsi_session *session = conn->session; |
865 | 868 | ||
866 | phwi_ctrlr = phba->phwi_ctrlr; | 869 | phwi_ctrlr = phba->phwi_ctrlr; |
867 | pwrb_context = &phwi_ctrlr->wrb_context[((psol-> | 870 | if (ring_mode) { |
868 | dw[offsetof(struct amap_sol_cqe, cid) / 32] & | 871 | psgl_handle = phba->sgl_hndl_array[((psol-> |
869 | SOL_CID_MASK) >> 6)]; | 872 | dw[offsetof(struct amap_sol_cqe_ring, icd_index) / |
870 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | 873 | 32] & SOL_ICD_INDEX_MASK) >> 6)]; |
871 | dw[offsetof(struct amap_sol_cqe, wrb_index) / | 874 | pwrb_context = &phwi_ctrlr->wrb_context[psgl_handle->cid]; |
872 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; | 875 | task = psgl_handle->task; |
873 | task = pwrb_handle->pio_handle; | 876 | pwrb_handle = NULL; |
877 | } else { | ||
878 | pwrb_context = &phwi_ctrlr->wrb_context[((psol-> | ||
879 | dw[offsetof(struct amap_sol_cqe, cid) / 32] & | ||
880 | SOL_CID_MASK) >> 6)]; | ||
881 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | ||
882 | dw[offsetof(struct amap_sol_cqe, wrb_index) / | ||
883 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; | ||
884 | task = pwrb_handle->pio_handle; | ||
885 | } | ||
886 | |||
874 | io_task = task->dd_data; | 887 | io_task = task->dd_data; |
875 | spin_lock(&phba->mgmt_sgl_lock); | 888 | spin_lock(&phba->mgmt_sgl_lock); |
876 | free_mgmt_sgl_handle(phba, io_task->psgl_handle); | 889 | free_mgmt_sgl_handle(phba, io_task->psgl_handle); |
@@ -910,23 +923,31 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, | |||
910 | struct iscsi_wrb *pwrb = NULL; | 923 | struct iscsi_wrb *pwrb = NULL; |
911 | struct hwi_controller *phwi_ctrlr; | 924 | struct hwi_controller *phwi_ctrlr; |
912 | struct iscsi_task *task; | 925 | struct iscsi_task *task; |
926 | struct sgl_handle *psgl_handle = NULL; | ||
913 | unsigned int type; | 927 | unsigned int type; |
914 | struct iscsi_conn *conn = beiscsi_conn->conn; | 928 | struct iscsi_conn *conn = beiscsi_conn->conn; |
915 | struct iscsi_session *session = conn->session; | 929 | struct iscsi_session *session = conn->session; |
916 | 930 | ||
917 | phwi_ctrlr = phba->phwi_ctrlr; | 931 | phwi_ctrlr = phba->phwi_ctrlr; |
918 | pwrb_context = &phwi_ctrlr-> | 932 | if (ring_mode) { |
919 | wrb_context[((psol->dw[offsetof | 933 | psgl_handle = phba->sgl_hndl_array[((psol-> |
920 | (struct amap_sol_cqe, cid) / 32] | 934 | dw[offsetof(struct amap_sol_cqe_ring, icd_index) / |
921 | & SOL_CID_MASK) >> 6)]; | 935 | 32] & SOL_ICD_INDEX_MASK) >> 6)]; |
922 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | 936 | task = psgl_handle->task; |
923 | dw[offsetof(struct amap_sol_cqe, wrb_index) / | 937 | type = psgl_handle->type; |
924 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; | 938 | } else { |
925 | task = pwrb_handle->pio_handle; | 939 | pwrb_context = &phwi_ctrlr-> |
926 | pwrb = pwrb_handle->pwrb; | 940 | wrb_context[((psol->dw[offsetof |
927 | type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] & | 941 | (struct amap_sol_cqe, cid) / 32] |
942 | & SOL_CID_MASK) >> 6)]; | ||
943 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | ||
944 | dw[offsetof(struct amap_sol_cqe, wrb_index) / | ||
945 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; | ||
946 | task = pwrb_handle->pio_handle; | ||
947 | pwrb = pwrb_handle->pwrb; | ||
948 | type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] & | ||
928 | WRB_TYPE_MASK) >> 28; | 949 | WRB_TYPE_MASK) >> 28; |
929 | 950 | } | |
930 | spin_lock_bh(&session->lock); | 951 | spin_lock_bh(&session->lock); |
931 | switch (type) { | 952 | switch (type) { |
932 | case HWH_TYPE_IO: | 953 | case HWH_TYPE_IO: |
@@ -957,15 +978,24 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, | |||
957 | break; | 978 | break; |
958 | 979 | ||
959 | default: | 980 | default: |
960 | shost_printk(KERN_WARNING, phba->shost, | 981 | if (ring_mode) |
961 | "In hwi_complete_cmd, unknown type = %d" | 982 | shost_printk(KERN_WARNING, phba->shost, |
962 | "wrb_index 0x%x CID 0x%x\n", type, | 983 | "In hwi_complete_cmd, unknown type = %d" |
963 | ((psol->dw[offsetof(struct amap_iscsi_wrb, | 984 | "icd_index 0x%x CID 0x%x\n", type, |
964 | type) / 32] & SOL_WRB_INDEX_MASK) >> 16), | 985 | ((psol->dw[offsetof(struct amap_sol_cqe_ring, |
965 | ((psol->dw[offsetof(struct amap_sol_cqe, | 986 | icd_index) / 32] & SOL_ICD_INDEX_MASK) >> 6), |
966 | cid) / 32] & SOL_CID_MASK) >> 6)); | 987 | psgl_handle->cid); |
988 | else | ||
989 | shost_printk(KERN_WARNING, phba->shost, | ||
990 | "In hwi_complete_cmd, unknown type = %d" | ||
991 | "wrb_index 0x%x CID 0x%x\n", type, | ||
992 | ((psol->dw[offsetof(struct amap_iscsi_wrb, | ||
993 | type) / 32] & SOL_WRB_INDEX_MASK) >> 16), | ||
994 | ((psol->dw[offsetof(struct amap_sol_cqe, | ||
995 | cid) / 32] & SOL_CID_MASK) >> 6)); | ||
967 | break; | 996 | break; |
968 | } | 997 | } |
998 | |||
969 | spin_unlock_bh(&session->lock); | 999 | spin_unlock_bh(&session->lock); |
970 | } | 1000 | } |
971 | 1001 | ||
@@ -1401,6 +1431,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1401 | unsigned int num_processed = 0; | 1431 | unsigned int num_processed = 0; |
1402 | unsigned int tot_nump = 0; | 1432 | unsigned int tot_nump = 0; |
1403 | struct beiscsi_conn *beiscsi_conn; | 1433 | struct beiscsi_conn *beiscsi_conn; |
1434 | struct sgl_handle *psgl_handle = NULL; | ||
1404 | struct beiscsi_hba *phba; | 1435 | struct beiscsi_hba *phba; |
1405 | 1436 | ||
1406 | cq = pbe_eq->cq; | 1437 | cq = pbe_eq->cq; |
@@ -1411,17 +1442,32 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1411 | CQE_VALID_MASK) { | 1442 | CQE_VALID_MASK) { |
1412 | be_dws_le_to_cpu(sol, sizeof(struct sol_cqe)); | 1443 | be_dws_le_to_cpu(sol, sizeof(struct sol_cqe)); |
1413 | 1444 | ||
1414 | beiscsi_conn = phba->conn_table[(u32) (sol-> | 1445 | if (ring_mode) { |
1446 | psgl_handle = phba->sgl_hndl_array[((sol-> | ||
1447 | dw[offsetof(struct amap_sol_cqe_ring, | ||
1448 | icd_index) / 32] & SOL_ICD_INDEX_MASK) | ||
1449 | >> 6)]; | ||
1450 | beiscsi_conn = phba->conn_table[psgl_handle->cid]; | ||
1451 | if (!beiscsi_conn || !beiscsi_conn->ep) { | ||
1452 | shost_printk(KERN_WARNING, phba->shost, | ||
1453 | "Connection table empty for cid = %d\n", | ||
1454 | psgl_handle->cid); | ||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1458 | } else { | ||
1459 | beiscsi_conn = phba->conn_table[(u32) (sol-> | ||
1415 | dw[offsetof(struct amap_sol_cqe, cid) / 32] & | 1460 | dw[offsetof(struct amap_sol_cqe, cid) / 32] & |
1416 | SOL_CID_MASK) >> 6]; | 1461 | SOL_CID_MASK) >> 6]; |
1417 | 1462 | ||
1418 | if (!beiscsi_conn || !beiscsi_conn->ep) { | 1463 | if (!beiscsi_conn || !beiscsi_conn->ep) { |
1419 | shost_printk(KERN_WARNING, phba->shost, | 1464 | shost_printk(KERN_WARNING, phba->shost, |
1420 | "Connection table empty for cid = %d\n", | 1465 | "Connection table empty for cid = %d\n", |
1421 | (u32)(sol->dw[offsetof(struct amap_sol_cqe, | 1466 | (u32)(sol->dw[offsetof(struct amap_sol_cqe, |
1422 | cid) / 32] & SOL_CID_MASK) >> 6); | 1467 | cid) / 32] & SOL_CID_MASK) >> 6); |
1423 | return 0; | 1468 | return 0; |
1424 | } | 1469 | } |
1470 | } | ||
1425 | 1471 | ||
1426 | if (num_processed >= 32) { | 1472 | if (num_processed >= 32) { |
1427 | hwi_ring_cq_db(phba, cq->id, | 1473 | hwi_ring_cq_db(phba, cq->id, |
@@ -1465,13 +1511,21 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1465 | case CMD_CXN_KILLED_ITT_INVALID: | 1511 | case CMD_CXN_KILLED_ITT_INVALID: |
1466 | case CMD_CXN_KILLED_SEQ_OUTOFORDER: | 1512 | case CMD_CXN_KILLED_SEQ_OUTOFORDER: |
1467 | case CMD_CXN_KILLED_INVALID_DATASN_RCVD: | 1513 | case CMD_CXN_KILLED_INVALID_DATASN_RCVD: |
1468 | SE_DEBUG(DBG_LVL_1, | 1514 | if (ring_mode) { |
1515 | SE_DEBUG(DBG_LVL_1, | ||
1516 | "CQ Error notification for cmd.. " | ||
1517 | "code %d cid 0x%x\n", | ||
1518 | sol->dw[offsetof(struct amap_sol_cqe, code) / | ||
1519 | 32] & CQE_CODE_MASK, psgl_handle->cid); | ||
1520 | } else { | ||
1521 | SE_DEBUG(DBG_LVL_1, | ||
1469 | "CQ Error notification for cmd.. " | 1522 | "CQ Error notification for cmd.. " |
1470 | "code %d cid 0x%x\n", | 1523 | "code %d cid 0x%x\n", |
1471 | sol->dw[offsetof(struct amap_sol_cqe, code) / | 1524 | sol->dw[offsetof(struct amap_sol_cqe, code) / |
1472 | 32] & CQE_CODE_MASK, | 1525 | 32] & CQE_CODE_MASK, |
1473 | (sol->dw[offsetof(struct amap_sol_cqe, cid) / | 1526 | (sol->dw[offsetof(struct amap_sol_cqe, cid) / |
1474 | 32] & SOL_CID_MASK)); | 1527 | 32] & SOL_CID_MASK)); |
1528 | } | ||
1475 | break; | 1529 | break; |
1476 | case UNSOL_DATA_DIGEST_ERROR_NOTIFY: | 1530 | case UNSOL_DATA_DIGEST_ERROR_NOTIFY: |
1477 | SE_DEBUG(DBG_LVL_1, | 1531 | SE_DEBUG(DBG_LVL_1, |
@@ -1493,23 +1547,37 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1493 | case CXN_KILLED_OVER_RUN_RESIDUAL: | 1547 | case CXN_KILLED_OVER_RUN_RESIDUAL: |
1494 | case CXN_KILLED_UNDER_RUN_RESIDUAL: | 1548 | case CXN_KILLED_UNDER_RUN_RESIDUAL: |
1495 | case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN: | 1549 | case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN: |
1496 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID " | 1550 | if (ring_mode) { |
1551 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID " | ||
1552 | "0x%x...\n", | ||
1553 | sol->dw[offsetof(struct amap_sol_cqe, code) / | ||
1554 | 32] & CQE_CODE_MASK, psgl_handle->cid); | ||
1555 | } else { | ||
1556 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID " | ||
1497 | "0x%x...\n", | 1557 | "0x%x...\n", |
1498 | sol->dw[offsetof(struct amap_sol_cqe, code) / | 1558 | sol->dw[offsetof(struct amap_sol_cqe, code) / |
1499 | 32] & CQE_CODE_MASK, | 1559 | 32] & CQE_CODE_MASK, |
1500 | sol->dw[offsetof(struct amap_sol_cqe, cid) / | 1560 | sol->dw[offsetof(struct amap_sol_cqe, cid) / |
1501 | 32] & CQE_CID_MASK); | 1561 | 32] & CQE_CID_MASK); |
1562 | } | ||
1502 | iscsi_conn_failure(beiscsi_conn->conn, | 1563 | iscsi_conn_failure(beiscsi_conn->conn, |
1503 | ISCSI_ERR_CONN_FAILED); | 1564 | ISCSI_ERR_CONN_FAILED); |
1504 | break; | 1565 | break; |
1505 | case CXN_KILLED_RST_SENT: | 1566 | case CXN_KILLED_RST_SENT: |
1506 | case CXN_KILLED_RST_RCVD: | 1567 | case CXN_KILLED_RST_RCVD: |
1507 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset" | 1568 | if (ring_mode) { |
1569 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset" | ||
1570 | "received/sent on CID 0x%x...\n", | ||
1571 | sol->dw[offsetof(struct amap_sol_cqe, code) / | ||
1572 | 32] & CQE_CODE_MASK, psgl_handle->cid); | ||
1573 | } else { | ||
1574 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset" | ||
1508 | "received/sent on CID 0x%x...\n", | 1575 | "received/sent on CID 0x%x...\n", |
1509 | sol->dw[offsetof(struct amap_sol_cqe, code) / | 1576 | sol->dw[offsetof(struct amap_sol_cqe, code) / |
1510 | 32] & CQE_CODE_MASK, | 1577 | 32] & CQE_CODE_MASK, |
1511 | sol->dw[offsetof(struct amap_sol_cqe, cid) / | 1578 | sol->dw[offsetof(struct amap_sol_cqe, cid) / |
1512 | 32] & CQE_CID_MASK); | 1579 | 32] & CQE_CID_MASK); |
1580 | } | ||
1513 | iscsi_conn_failure(beiscsi_conn->conn, | 1581 | iscsi_conn_failure(beiscsi_conn->conn, |
1514 | ISCSI_ERR_CONN_FAILED); | 1582 | ISCSI_ERR_CONN_FAILED); |
1515 | break; | 1583 | break; |
@@ -2674,7 +2742,7 @@ static int be_mcc_queues_create(struct beiscsi_hba *phba, | |||
2674 | goto mcc_cq_destroy; | 2742 | goto mcc_cq_destroy; |
2675 | 2743 | ||
2676 | /* Ask BE to create MCC queue */ | 2744 | /* Ask BE to create MCC queue */ |
2677 | if (be_cmd_mccq_create(phba, q, cq)) | 2745 | if (beiscsi_cmd_mccq_create(phba, q, cq)) |
2678 | goto mcc_q_free; | 2746 | goto mcc_q_free; |
2679 | 2747 | ||
2680 | return 0; | 2748 | return 0; |
@@ -2735,6 +2803,10 @@ static int hwi_init_port(struct beiscsi_hba *phba) | |||
2735 | goto error; | 2803 | goto error; |
2736 | } | 2804 | } |
2737 | 2805 | ||
2806 | if (phba->fw_config.iscsi_features == 0x1) | ||
2807 | ring_mode = 1; | ||
2808 | else | ||
2809 | ring_mode = 0; | ||
2738 | status = mgmt_get_fw_config(ctrl, phba); | 2810 | status = mgmt_get_fw_config(ctrl, phba); |
2739 | if (status != 0) { | 2811 | if (status != 0) { |
2740 | shost_printk(KERN_ERR, phba->shost, | 2812 | shost_printk(KERN_ERR, phba->shost, |
@@ -2869,6 +2941,17 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) | |||
2869 | phba->io_sgl_hndl_avbl = 0; | 2941 | phba->io_sgl_hndl_avbl = 0; |
2870 | phba->eh_sgl_hndl_avbl = 0; | 2942 | phba->eh_sgl_hndl_avbl = 0; |
2871 | 2943 | ||
2944 | if (ring_mode) { | ||
2945 | phba->sgl_hndl_array = kzalloc(sizeof(struct sgl_handle *) * | ||
2946 | phba->params.icds_per_ctrl, | ||
2947 | GFP_KERNEL); | ||
2948 | if (!phba->sgl_hndl_array) { | ||
2949 | shost_printk(KERN_ERR, phba->shost, | ||
2950 | "Mem Alloc Failed. Failing to load\n"); | ||
2951 | return -ENOMEM; | ||
2952 | } | ||
2953 | } | ||
2954 | |||
2872 | mem_descr_sglh = phba->init_mem; | 2955 | mem_descr_sglh = phba->init_mem; |
2873 | mem_descr_sglh += HWI_MEM_SGLH; | 2956 | mem_descr_sglh += HWI_MEM_SGLH; |
2874 | if (1 == mem_descr_sglh->num_elements) { | 2957 | if (1 == mem_descr_sglh->num_elements) { |
@@ -2876,6 +2959,8 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) | |||
2876 | phba->params.ios_per_ctrl, | 2959 | phba->params.ios_per_ctrl, |
2877 | GFP_KERNEL); | 2960 | GFP_KERNEL); |
2878 | if (!phba->io_sgl_hndl_base) { | 2961 | if (!phba->io_sgl_hndl_base) { |
2962 | if (ring_mode) | ||
2963 | kfree(phba->sgl_hndl_array); | ||
2879 | shost_printk(KERN_ERR, phba->shost, | 2964 | shost_printk(KERN_ERR, phba->shost, |
2880 | "Mem Alloc Failed. Failing to load\n"); | 2965 | "Mem Alloc Failed. Failing to load\n"); |
2881 | return -ENOMEM; | 2966 | return -ENOMEM; |
@@ -3060,6 +3145,8 @@ static int beiscsi_init_port(struct beiscsi_hba *phba) | |||
3060 | if (hba_setup_cid_tbls(phba)) { | 3145 | if (hba_setup_cid_tbls(phba)) { |
3061 | shost_printk(KERN_ERR, phba->shost, | 3146 | shost_printk(KERN_ERR, phba->shost, |
3062 | "Failed in hba_setup_cid_tbls\n"); | 3147 | "Failed in hba_setup_cid_tbls\n"); |
3148 | if (ring_mode) | ||
3149 | kfree(phba->sgl_hndl_array); | ||
3063 | kfree(phba->io_sgl_hndl_base); | 3150 | kfree(phba->io_sgl_hndl_base); |
3064 | kfree(phba->eh_sgl_hndl_base); | 3151 | kfree(phba->eh_sgl_hndl_base); |
3065 | goto do_cleanup_ctrlr; | 3152 | goto do_cleanup_ctrlr; |
@@ -3110,6 +3197,8 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba) | |||
3110 | "mgmt_epfw_cleanup FAILED \n"); | 3197 | "mgmt_epfw_cleanup FAILED \n"); |
3111 | hwi_cleanup(phba); | 3198 | hwi_cleanup(phba); |
3112 | hwi_purge_eq(phba); | 3199 | hwi_purge_eq(phba); |
3200 | if (ring_mode) | ||
3201 | kfree(phba->sgl_hndl_array); | ||
3113 | kfree(phba->io_sgl_hndl_base); | 3202 | kfree(phba->io_sgl_hndl_base); |
3114 | kfree(phba->eh_sgl_hndl_base); | 3203 | kfree(phba->eh_sgl_hndl_base); |
3115 | kfree(phba->cid_array); | 3204 | kfree(phba->cid_array); |
@@ -3194,7 +3283,8 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn, | |||
3194 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb)); | 3283 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb)); |
3195 | 3284 | ||
3196 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; | 3285 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; |
3197 | doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) | 3286 | if (!ring_mode) |
3287 | doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) | ||
3198 | << DB_DEF_PDU_WRB_INDEX_SHIFT; | 3288 | << DB_DEF_PDU_WRB_INDEX_SHIFT; |
3199 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 3289 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
3200 | 3290 | ||
@@ -3280,7 +3370,14 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) | |||
3280 | itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle-> | 3370 | itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle-> |
3281 | wrb_index << 16) | (unsigned int) | 3371 | wrb_index << 16) | (unsigned int) |
3282 | (io_task->psgl_handle->sgl_index)); | 3372 | (io_task->psgl_handle->sgl_index)); |
3283 | io_task->pwrb_handle->pio_handle = task; | 3373 | if (ring_mode) { |
3374 | phba->sgl_hndl_array[io_task->psgl_handle->sgl_index - | ||
3375 | phba->fw_config.iscsi_cid_start] = | ||
3376 | io_task->psgl_handle; | ||
3377 | io_task->psgl_handle->task = task; | ||
3378 | io_task->psgl_handle->cid = beiscsi_conn->beiscsi_conn_cid; | ||
3379 | } else | ||
3380 | io_task->pwrb_handle->pio_handle = task; | ||
3284 | 3381 | ||
3285 | io_task->cmd_bhs->iscsi_hdr.itt = itt; | 3382 | io_task->cmd_bhs->iscsi_hdr.itt = itt; |
3286 | return 0; | 3383 | return 0; |
@@ -3363,11 +3460,17 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, | |||
3363 | ISCSI_OPCODE_SCSI_DATA_OUT); | 3460 | ISCSI_OPCODE_SCSI_DATA_OUT); |
3364 | AMAP_SET_BITS(struct amap_pdu_data_out, final_bit, | 3461 | AMAP_SET_BITS(struct amap_pdu_data_out, final_bit, |
3365 | &io_task->cmd_bhs->iscsi_data_pdu, 1); | 3462 | &io_task->cmd_bhs->iscsi_data_pdu, 1); |
3366 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3463 | if (ring_mode) |
3464 | io_task->psgl_handle->type = INI_WR_CMD; | ||
3465 | else | ||
3466 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3367 | INI_WR_CMD); | 3467 | INI_WR_CMD); |
3368 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); | 3468 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); |
3369 | } else { | 3469 | } else { |
3370 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3470 | if (ring_mode) |
3471 | io_task->psgl_handle->type = INI_RD_CMD; | ||
3472 | else | ||
3473 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3371 | INI_RD_CMD); | 3474 | INI_RD_CMD); |
3372 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); | 3475 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); |
3373 | } | 3476 | } |
@@ -3393,7 +3496,8 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, | |||
3393 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); | 3496 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); |
3394 | 3497 | ||
3395 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; | 3498 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; |
3396 | doorbell |= (io_task->pwrb_handle->wrb_index & | 3499 | if (!ring_mode) |
3500 | doorbell |= (io_task->pwrb_handle->wrb_index & | ||
3397 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; | 3501 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; |
3398 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 3502 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
3399 | 3503 | ||
@@ -3427,19 +3531,28 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3427 | 3531 | ||
3428 | switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { | 3532 | switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { |
3429 | case ISCSI_OP_LOGIN: | 3533 | case ISCSI_OP_LOGIN: |
3430 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3534 | if (ring_mode) |
3535 | io_task->psgl_handle->type = TGT_DM_CMD; | ||
3536 | else | ||
3537 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3431 | TGT_DM_CMD); | 3538 | TGT_DM_CMD); |
3432 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3539 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3433 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1); | 3540 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1); |
3434 | hwi_write_buffer(pwrb, task); | 3541 | hwi_write_buffer(pwrb, task); |
3435 | break; | 3542 | break; |
3436 | case ISCSI_OP_NOOP_OUT: | 3543 | case ISCSI_OP_NOOP_OUT: |
3437 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3544 | if (ring_mode) |
3545 | io_task->psgl_handle->type = INI_RD_CMD; | ||
3546 | else | ||
3547 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3438 | INI_RD_CMD); | 3548 | INI_RD_CMD); |
3439 | hwi_write_buffer(pwrb, task); | 3549 | hwi_write_buffer(pwrb, task); |
3440 | break; | 3550 | break; |
3441 | case ISCSI_OP_TEXT: | 3551 | case ISCSI_OP_TEXT: |
3442 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3552 | if (ring_mode) |
3553 | io_task->psgl_handle->type = INI_WR_CMD; | ||
3554 | else | ||
3555 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3443 | INI_WR_CMD); | 3556 | INI_WR_CMD); |
3444 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); | 3557 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); |
3445 | hwi_write_buffer(pwrb, task); | 3558 | hwi_write_buffer(pwrb, task); |
@@ -3462,13 +3575,19 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3462 | mgmt_invalidate_icds(phba, | 3575 | mgmt_invalidate_icds(phba, |
3463 | aborted_io_task->psgl_handle->sgl_index, | 3576 | aborted_io_task->psgl_handle->sgl_index, |
3464 | cid); | 3577 | cid); |
3465 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3578 | if (ring_mode) |
3579 | io_task->psgl_handle->type = INI_TMF_CMD; | ||
3580 | else | ||
3581 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3466 | INI_TMF_CMD); | 3582 | INI_TMF_CMD); |
3467 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3583 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3468 | hwi_write_buffer(pwrb, task); | 3584 | hwi_write_buffer(pwrb, task); |
3469 | break; | 3585 | break; |
3470 | case ISCSI_OP_LOGOUT: | 3586 | case ISCSI_OP_LOGOUT: |
3471 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3587 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3588 | if (ring_mode) | ||
3589 | io_task->psgl_handle->type = HWH_TYPE_LOGOUT; | ||
3590 | else | ||
3472 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3591 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3473 | HWH_TYPE_LOGOUT); | 3592 | HWH_TYPE_LOGOUT); |
3474 | hwi_write_buffer(pwrb, task); | 3593 | hwi_write_buffer(pwrb, task); |
@@ -3487,7 +3606,8 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3487 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); | 3606 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); |
3488 | 3607 | ||
3489 | doorbell |= cid & DB_WRB_POST_CID_MASK; | 3608 | doorbell |= cid & DB_WRB_POST_CID_MASK; |
3490 | doorbell |= (io_task->pwrb_handle->wrb_index & | 3609 | if (!ring_mode) |
3610 | doorbell |= (io_task->pwrb_handle->wrb_index & | ||
3491 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; | 3611 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; |
3492 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 3612 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
3493 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); | 3613 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); |
@@ -3797,6 +3917,7 @@ static int __init beiscsi_module_init(void) | |||
3797 | "beiscsi pci driver.\n"); | 3917 | "beiscsi pci driver.\n"); |
3798 | goto unregister_iscsi_transport; | 3918 | goto unregister_iscsi_transport; |
3799 | } | 3919 | } |
3920 | ring_mode = 0; | ||
3800 | return 0; | 3921 | return 0; |
3801 | 3922 | ||
3802 | unregister_iscsi_transport: | 3923 | unregister_iscsi_transport: |