aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/isert
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-11 15:57:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-11 15:57:19 -0400
commit6d2fa9e141ea56a571ec842fd4f3a86bea44a203 (patch)
treee419f95b7d080046f0f4d4d5041b42a0889f2f0a /drivers/infiniband/ulp/isert
parent0fb3767b0a5601dd0d528bc8dbefc0567a34b7ec (diff)
parentca40d24eb8fc3c194b4439493ecf6b2d703812b8 (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger: "Lots of activity this round on performance improvements in target-core while benchmarking the prototype scsi-mq initiator code with vhost-scsi fabric ports, along with a number of iscsi/iser-target improvements and hardening fixes for exception path cases post v3.10 merge. The highlights include: - Make persistent reservations APTPL buffer allocated on-demand, and drop per t10_reservation buffer. (grover) - Make virtual LUN=0 a NULLIO device, and skip allocation of NULLIO device pages (grover) - Add transport_cmd_check_stop write_pending bit to avoid extra access of ->t_state_lock is WRITE I/O submission fast-path. (nab) - Drop unnecessary CMD_T_DEV_ACTIVE check from transport_lun_remove_cmd to avoid extra access of ->t_state_lock in release fast-path. (nab) - Avoid extra t_state_lock access in __target_execute_cmd fast-path (nab) - Drop unnecessary vhost-scsi wait_for_tasks=true usage + ->t_state_lock access in release fast-path. (nab) - Convert vhost-scsi to use modern se_cmd->cmd_kref TARGET_SCF_ACK_KREF usage (nab) - Add tracepoints for SCSI commands being processed (roland) - Refactoring of iscsi-target handling of ISCSI_OP_NOOP + ISCSI_OP_TEXT to be transport independent (nab) - Add iscsi-target SendTargets=$IQN support for in-band discovery (nab) - Add iser-target support for in-band discovery (nab + Or) - Add iscsi-target demo-mode TPG authentication context support (nab) - Fix isert_put_reject payload buffer post (nab) - Fix iscsit_add_reject* usage for iser (nab) - Fix iscsit_sequence_cmd reject handling for iser (nab) - Fix ISCSI_OP_SCSI_TMFUNC handling for iser (nab) - Fix session reset bug with RDMA_CM_EVENT_DISCONNECTED (nab) The last five iscsi/iser-target items are CC'ed to stable, as they do address issues present in v3.10 code. They are certainly larger than I'd like for stable patch set, but are important to ensure proper REJECT exception handling in iser-target for 3.10.y" * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (51 commits) iser-target: Ignore non TEXT + LOGOUT opcodes for discovery target: make queue_tm_rsp() return void target: remove unused codes from enum tcm_tmrsp_table iscsi-target: kstrtou* configfs attribute parameter cleanups iscsi-target: Fix tfc_tpg_auth_cit configfs length overflow iscsi-target: Fix tfc_tpg_nacl_auth_cit configfs length overflow iser-target: Add support for ISCSI_OP_TEXT opcode + payload handling iser-target: Rename sense_buf_[dma,len] to pdu_[dma,len] iser-target: Add vendor_err debug output target: Add (obsolete) checking for PMI/LBA fields in READ CAPACITY(10) target: Return correct sense data for IO past the end of a device target: Add tracepoints for SCSI commands being processed iser-target: Fix session reset bug with RDMA_CM_EVENT_DISCONNECTED iscsi-target: Fix ISCSI_OP_SCSI_TMFUNC handling for iser iscsi-target: Fix iscsit_sequence_cmd reject handling for iser iscsi-target: Fix iscsit_add_reject* usage for iser iser-target: Fix isert_put_reject payload buffer post iscsi-target: missing kfree() on error path iscsi-target: Drop left-over iscsi_conn->bad_hdr target: Make core_scsi3_update_and_write_aptpl return sense_reason_t ...
Diffstat (limited to 'drivers/infiniband/ulp/isert')
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c268
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.h5
2 files changed, 228 insertions, 45 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 2693129055c1..3f62041222f2 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -388,6 +388,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
388 init_waitqueue_head(&isert_conn->conn_wait_comp_err); 388 init_waitqueue_head(&isert_conn->conn_wait_comp_err);
389 kref_init(&isert_conn->conn_kref); 389 kref_init(&isert_conn->conn_kref);
390 kref_get(&isert_conn->conn_kref); 390 kref_get(&isert_conn->conn_kref);
391 mutex_init(&isert_conn->conn_mutex);
391 392
392 cma_id->context = isert_conn; 393 cma_id->context = isert_conn;
393 isert_conn->conn_cm_id = cma_id; 394 isert_conn->conn_cm_id = cma_id;
@@ -540,15 +541,32 @@ isert_disconnect_work(struct work_struct *work)
540 struct isert_conn, conn_logout_work); 541 struct isert_conn, conn_logout_work);
541 542
542 pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); 543 pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
543 544 mutex_lock(&isert_conn->conn_mutex);
544 isert_conn->state = ISER_CONN_DOWN; 545 isert_conn->state = ISER_CONN_DOWN;
545 546
546 if (isert_conn->post_recv_buf_count == 0 && 547 if (isert_conn->post_recv_buf_count == 0 &&
547 atomic_read(&isert_conn->post_send_buf_count) == 0) { 548 atomic_read(&isert_conn->post_send_buf_count) == 0) {
548 pr_debug("Calling wake_up(&isert_conn->conn_wait);\n"); 549 pr_debug("Calling wake_up(&isert_conn->conn_wait);\n");
549 wake_up(&isert_conn->conn_wait); 550 mutex_unlock(&isert_conn->conn_mutex);
551 goto wake_up;
552 }
553 if (!isert_conn->conn_cm_id) {
554 mutex_unlock(&isert_conn->conn_mutex);
555 isert_put_conn(isert_conn);
556 return;
550 } 557 }
558 if (!isert_conn->logout_posted) {
559 pr_debug("Calling rdma_disconnect for !logout_posted from"
560 " isert_disconnect_work\n");
561 rdma_disconnect(isert_conn->conn_cm_id);
562 mutex_unlock(&isert_conn->conn_mutex);
563 iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
564 goto wake_up;
565 }
566 mutex_unlock(&isert_conn->conn_mutex);
551 567
568wake_up:
569 wake_up(&isert_conn->conn_wait);
552 isert_put_conn(isert_conn); 570 isert_put_conn(isert_conn);
553} 571}
554 572
@@ -934,16 +952,11 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn,
934 } 952 }
935 953
936sequence_cmd: 954sequence_cmd:
937 rc = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); 955 rc = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
938 956
939 if (!rc && dump_payload == false && unsol_data) 957 if (!rc && dump_payload == false && unsol_data)
940 iscsit_set_unsoliticed_dataout(cmd); 958 iscsit_set_unsoliticed_dataout(cmd);
941 959
942 if (rc == CMDSN_ERROR_CANNOT_RECOVER)
943 return iscsit_add_reject_from_cmd(
944 ISCSI_REASON_PROTOCOL_ERROR,
945 1, 0, (unsigned char *)hdr, cmd);
946
947 return 0; 960 return 0;
948} 961}
949 962
@@ -1001,17 +1014,71 @@ isert_handle_iscsi_dataout(struct isert_conn *isert_conn,
1001} 1014}
1002 1015
1003static int 1016static int
1017isert_handle_nop_out(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
1018 struct iser_rx_desc *rx_desc, unsigned char *buf)
1019{
1020 struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd;
1021 struct iscsi_conn *conn = isert_conn->conn;
1022 struct iscsi_nopout *hdr = (struct iscsi_nopout *)buf;
1023 int rc;
1024
1025 rc = iscsit_setup_nop_out(conn, cmd, hdr);
1026 if (rc < 0)
1027 return rc;
1028 /*
1029 * FIXME: Add support for NOPOUT payload using unsolicited RDMA payload
1030 */
1031
1032 return iscsit_process_nop_out(conn, cmd, hdr);
1033}
1034
1035static int
1036isert_handle_text_cmd(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
1037 struct iser_rx_desc *rx_desc, struct iscsi_text *hdr)
1038{
1039 struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd;
1040 struct iscsi_conn *conn = isert_conn->conn;
1041 u32 payload_length = ntoh24(hdr->dlength);
1042 int rc;
1043 unsigned char *text_in;
1044
1045 rc = iscsit_setup_text_cmd(conn, cmd, hdr);
1046 if (rc < 0)
1047 return rc;
1048
1049 text_in = kzalloc(payload_length, GFP_KERNEL);
1050 if (!text_in) {
1051 pr_err("Unable to allocate text_in of payload_length: %u\n",
1052 payload_length);
1053 return -ENOMEM;
1054 }
1055 cmd->text_in_ptr = text_in;
1056
1057 memcpy(cmd->text_in_ptr, &rx_desc->data[0], payload_length);
1058
1059 return iscsit_process_text_cmd(conn, cmd, hdr);
1060}
1061
1062static int
1004isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, 1063isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
1005 uint32_t read_stag, uint64_t read_va, 1064 uint32_t read_stag, uint64_t read_va,
1006 uint32_t write_stag, uint64_t write_va) 1065 uint32_t write_stag, uint64_t write_va)
1007{ 1066{
1008 struct iscsi_hdr *hdr = &rx_desc->iscsi_header; 1067 struct iscsi_hdr *hdr = &rx_desc->iscsi_header;
1009 struct iscsi_conn *conn = isert_conn->conn; 1068 struct iscsi_conn *conn = isert_conn->conn;
1069 struct iscsi_session *sess = conn->sess;
1010 struct iscsi_cmd *cmd; 1070 struct iscsi_cmd *cmd;
1011 struct isert_cmd *isert_cmd; 1071 struct isert_cmd *isert_cmd;
1012 int ret = -EINVAL; 1072 int ret = -EINVAL;
1013 u8 opcode = (hdr->opcode & ISCSI_OPCODE_MASK); 1073 u8 opcode = (hdr->opcode & ISCSI_OPCODE_MASK);
1014 1074
1075 if (sess->sess_ops->SessionType &&
1076 (!(opcode & ISCSI_OP_TEXT) || !(opcode & ISCSI_OP_LOGOUT))) {
1077 pr_err("Got illegal opcode: 0x%02x in SessionType=Discovery,"
1078 " ignoring\n", opcode);
1079 return 0;
1080 }
1081
1015 switch (opcode) { 1082 switch (opcode) {
1016 case ISCSI_OP_SCSI_CMD: 1083 case ISCSI_OP_SCSI_CMD:
1017 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); 1084 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
@@ -1032,7 +1099,9 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
1032 if (!cmd) 1099 if (!cmd)
1033 break; 1100 break;
1034 1101
1035 ret = iscsit_handle_nop_out(conn, cmd, (unsigned char *)hdr); 1102 isert_cmd = container_of(cmd, struct isert_cmd, iscsi_cmd);
1103 ret = isert_handle_nop_out(isert_conn, isert_cmd,
1104 rx_desc, (unsigned char *)hdr);
1036 break; 1105 break;
1037 case ISCSI_OP_SCSI_DATA_OUT: 1106 case ISCSI_OP_SCSI_DATA_OUT:
1038 ret = isert_handle_iscsi_dataout(isert_conn, rx_desc, 1107 ret = isert_handle_iscsi_dataout(isert_conn, rx_desc,
@@ -1057,6 +1126,15 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
1057 SECONDS_FOR_LOGOUT_COMP * 1126 SECONDS_FOR_LOGOUT_COMP *
1058 HZ); 1127 HZ);
1059 break; 1128 break;
1129 case ISCSI_OP_TEXT:
1130 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
1131 if (!cmd)
1132 break;
1133
1134 isert_cmd = container_of(cmd, struct isert_cmd, iscsi_cmd);
1135 ret = isert_handle_text_cmd(isert_conn, isert_cmd,
1136 rx_desc, (struct iscsi_text *)hdr);
1137 break;
1060 default: 1138 default:
1061 pr_err("Got unknown iSCSI OpCode: 0x%02x\n", opcode); 1139 pr_err("Got unknown iSCSI OpCode: 0x%02x\n", opcode);
1062 dump_stack(); 1140 dump_stack();
@@ -1184,14 +1262,12 @@ isert_put_cmd(struct isert_cmd *isert_cmd)
1184{ 1262{
1185 struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; 1263 struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd;
1186 struct isert_conn *isert_conn = isert_cmd->conn; 1264 struct isert_conn *isert_conn = isert_cmd->conn;
1187 struct iscsi_conn *conn; 1265 struct iscsi_conn *conn = isert_conn->conn;
1188 1266
1189 pr_debug("Entering isert_put_cmd: %p\n", isert_cmd); 1267 pr_debug("Entering isert_put_cmd: %p\n", isert_cmd);
1190 1268
1191 switch (cmd->iscsi_opcode) { 1269 switch (cmd->iscsi_opcode) {
1192 case ISCSI_OP_SCSI_CMD: 1270 case ISCSI_OP_SCSI_CMD:
1193 conn = isert_conn->conn;
1194
1195 spin_lock_bh(&conn->cmd_lock); 1271 spin_lock_bh(&conn->cmd_lock);
1196 if (!list_empty(&cmd->i_conn_node)) 1272 if (!list_empty(&cmd->i_conn_node))
1197 list_del(&cmd->i_conn_node); 1273 list_del(&cmd->i_conn_node);
@@ -1201,16 +1277,19 @@ isert_put_cmd(struct isert_cmd *isert_cmd)
1201 iscsit_stop_dataout_timer(cmd); 1277 iscsit_stop_dataout_timer(cmd);
1202 1278
1203 isert_unmap_cmd(isert_cmd, isert_conn); 1279 isert_unmap_cmd(isert_cmd, isert_conn);
1204 /* 1280 transport_generic_free_cmd(&cmd->se_cmd, 0);
1205 * Fall-through 1281 break;
1206 */
1207 case ISCSI_OP_SCSI_TMFUNC: 1282 case ISCSI_OP_SCSI_TMFUNC:
1283 spin_lock_bh(&conn->cmd_lock);
1284 if (!list_empty(&cmd->i_conn_node))
1285 list_del(&cmd->i_conn_node);
1286 spin_unlock_bh(&conn->cmd_lock);
1287
1208 transport_generic_free_cmd(&cmd->se_cmd, 0); 1288 transport_generic_free_cmd(&cmd->se_cmd, 0);
1209 break; 1289 break;
1210 case ISCSI_OP_REJECT: 1290 case ISCSI_OP_REJECT:
1211 case ISCSI_OP_NOOP_OUT: 1291 case ISCSI_OP_NOOP_OUT:
1212 conn = isert_conn->conn; 1292 case ISCSI_OP_TEXT:
1213
1214 spin_lock_bh(&conn->cmd_lock); 1293 spin_lock_bh(&conn->cmd_lock);
1215 if (!list_empty(&cmd->i_conn_node)) 1294 if (!list_empty(&cmd->i_conn_node))
1216 list_del(&cmd->i_conn_node); 1295 list_del(&cmd->i_conn_node);
@@ -1222,6 +1301,9 @@ isert_put_cmd(struct isert_cmd *isert_cmd)
1222 * associated cmd->se_cmd needs to be released. 1301 * associated cmd->se_cmd needs to be released.
1223 */ 1302 */
1224 if (cmd->se_cmd.se_tfo != NULL) { 1303 if (cmd->se_cmd.se_tfo != NULL) {
1304 pr_debug("Calling transport_generic_free_cmd from"
1305 " isert_put_cmd for 0x%02x\n",
1306 cmd->iscsi_opcode);
1225 transport_generic_free_cmd(&cmd->se_cmd, 0); 1307 transport_generic_free_cmd(&cmd->se_cmd, 0);
1226 break; 1308 break;
1227 } 1309 }
@@ -1249,11 +1331,11 @@ static void
1249isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd, 1331isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd,
1250 struct ib_device *ib_dev) 1332 struct ib_device *ib_dev)
1251{ 1333{
1252 if (isert_cmd->sense_buf_dma != 0) { 1334 if (isert_cmd->pdu_buf_dma != 0) {
1253 pr_debug("Calling ib_dma_unmap_single for isert_cmd->sense_buf_dma\n"); 1335 pr_debug("Calling ib_dma_unmap_single for isert_cmd->pdu_buf_dma\n");
1254 ib_dma_unmap_single(ib_dev, isert_cmd->sense_buf_dma, 1336 ib_dma_unmap_single(ib_dev, isert_cmd->pdu_buf_dma,
1255 isert_cmd->sense_buf_len, DMA_TO_DEVICE); 1337 isert_cmd->pdu_buf_len, DMA_TO_DEVICE);
1256 isert_cmd->sense_buf_dma = 0; 1338 isert_cmd->pdu_buf_dma = 0;
1257 } 1339 }
1258 1340
1259 isert_unmap_tx_desc(tx_desc, ib_dev); 1341 isert_unmap_tx_desc(tx_desc, ib_dev);
@@ -1318,8 +1400,8 @@ isert_do_control_comp(struct work_struct *work)
1318 atomic_dec(&isert_conn->post_send_buf_count); 1400 atomic_dec(&isert_conn->post_send_buf_count);
1319 1401
1320 cmd->i_state = ISTATE_SENT_STATUS; 1402 cmd->i_state = ISTATE_SENT_STATUS;
1321 complete(&cmd->reject_comp);
1322 isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev); 1403 isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
1404 break;
1323 case ISTATE_SEND_LOGOUTRSP: 1405 case ISTATE_SEND_LOGOUTRSP:
1324 pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); 1406 pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n");
1325 /* 1407 /*
@@ -1329,6 +1411,11 @@ isert_do_control_comp(struct work_struct *work)
1329 isert_conn->logout_posted = true; 1411 isert_conn->logout_posted = true;
1330 iscsit_logout_post_handler(cmd, cmd->conn); 1412 iscsit_logout_post_handler(cmd, cmd->conn);
1331 break; 1413 break;
1414 case ISTATE_SEND_TEXTRSP:
1415 atomic_dec(&isert_conn->post_send_buf_count);
1416 cmd->i_state = ISTATE_SENT_STATUS;
1417 isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
1418 break;
1332 default: 1419 default:
1333 pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state); 1420 pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state);
1334 dump_stack(); 1421 dump_stack();
@@ -1345,7 +1432,9 @@ isert_response_completion(struct iser_tx_desc *tx_desc,
1345 struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; 1432 struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd;
1346 1433
1347 if (cmd->i_state == ISTATE_SEND_TASKMGTRSP || 1434 if (cmd->i_state == ISTATE_SEND_TASKMGTRSP ||
1348 cmd->i_state == ISTATE_SEND_LOGOUTRSP) { 1435 cmd->i_state == ISTATE_SEND_LOGOUTRSP ||
1436 cmd->i_state == ISTATE_SEND_REJECT ||
1437 cmd->i_state == ISTATE_SEND_TEXTRSP) {
1349 isert_unmap_tx_desc(tx_desc, ib_dev); 1438 isert_unmap_tx_desc(tx_desc, ib_dev);
1350 1439
1351 INIT_WORK(&isert_cmd->comp_work, isert_do_control_comp); 1440 INIT_WORK(&isert_cmd->comp_work, isert_do_control_comp);
@@ -1419,7 +1508,11 @@ isert_cq_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn)
1419 pr_debug("isert_cq_comp_err >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); 1508 pr_debug("isert_cq_comp_err >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1420 pr_debug("Calling wake_up from isert_cq_comp_err\n"); 1509 pr_debug("Calling wake_up from isert_cq_comp_err\n");
1421 1510
1422 isert_conn->state = ISER_CONN_TERMINATING; 1511 mutex_lock(&isert_conn->conn_mutex);
1512 if (isert_conn->state != ISER_CONN_DOWN)
1513 isert_conn->state = ISER_CONN_TERMINATING;
1514 mutex_unlock(&isert_conn->conn_mutex);
1515
1423 wake_up(&isert_conn->conn_wait_comp_err); 1516 wake_up(&isert_conn->conn_wait_comp_err);
1424 } 1517 }
1425} 1518}
@@ -1445,6 +1538,7 @@ isert_cq_tx_work(struct work_struct *work)
1445 } else { 1538 } else {
1446 pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); 1539 pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n");
1447 pr_debug("TX wc.status: 0x%08x\n", wc.status); 1540 pr_debug("TX wc.status: 0x%08x\n", wc.status);
1541 pr_debug("TX wc.vendor_err: 0x%08x\n", wc.vendor_err);
1448 atomic_dec(&isert_conn->post_send_buf_count); 1542 atomic_dec(&isert_conn->post_send_buf_count);
1449 isert_cq_comp_err(tx_desc, isert_conn); 1543 isert_cq_comp_err(tx_desc, isert_conn);
1450 } 1544 }
@@ -1484,9 +1578,11 @@ isert_cq_rx_work(struct work_struct *work)
1484 isert_rx_completion(rx_desc, isert_conn, xfer_len); 1578 isert_rx_completion(rx_desc, isert_conn, xfer_len);
1485 } else { 1579 } else {
1486 pr_debug("RX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); 1580 pr_debug("RX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n");
1487 if (wc.status != IB_WC_WR_FLUSH_ERR) 1581 if (wc.status != IB_WC_WR_FLUSH_ERR) {
1488 pr_debug("RX wc.status: 0x%08x\n", wc.status); 1582 pr_debug("RX wc.status: 0x%08x\n", wc.status);
1489 1583 pr_debug("RX wc.vendor_err: 0x%08x\n",
1584 wc.vendor_err);
1585 }
1490 isert_conn->post_recv_buf_count--; 1586 isert_conn->post_recv_buf_count--;
1491 isert_cq_comp_err(NULL, isert_conn); 1587 isert_cq_comp_err(NULL, isert_conn);
1492 } 1588 }
@@ -1543,7 +1639,7 @@ isert_put_response(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
1543 (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) { 1639 (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
1544 struct ib_device *ib_dev = isert_conn->conn_cm_id->device; 1640 struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
1545 struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1]; 1641 struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1];
1546 u32 padding, sense_len; 1642 u32 padding, pdu_len;
1547 1643
1548 put_unaligned_be16(cmd->se_cmd.scsi_sense_length, 1644 put_unaligned_be16(cmd->se_cmd.scsi_sense_length,
1549 cmd->sense_buffer); 1645 cmd->sense_buffer);
@@ -1551,15 +1647,15 @@ isert_put_response(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
1551 1647
1552 padding = -(cmd->se_cmd.scsi_sense_length) & 3; 1648 padding = -(cmd->se_cmd.scsi_sense_length) & 3;
1553 hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length); 1649 hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length);
1554 sense_len = cmd->se_cmd.scsi_sense_length + padding; 1650 pdu_len = cmd->se_cmd.scsi_sense_length + padding;
1555 1651
1556 isert_cmd->sense_buf_dma = ib_dma_map_single(ib_dev, 1652 isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev,
1557 (void *)cmd->sense_buffer, sense_len, 1653 (void *)cmd->sense_buffer, pdu_len,
1558 DMA_TO_DEVICE); 1654 DMA_TO_DEVICE);
1559 1655
1560 isert_cmd->sense_buf_len = sense_len; 1656 isert_cmd->pdu_buf_len = pdu_len;
1561 tx_dsg->addr = isert_cmd->sense_buf_dma; 1657 tx_dsg->addr = isert_cmd->pdu_buf_dma;
1562 tx_dsg->length = sense_len; 1658 tx_dsg->length = pdu_len;
1563 tx_dsg->lkey = isert_conn->conn_mr->lkey; 1659 tx_dsg->lkey = isert_conn->conn_mr->lkey;
1564 isert_cmd->tx_desc.num_sge = 2; 1660 isert_cmd->tx_desc.num_sge = 2;
1565 } 1661 }
@@ -1637,11 +1733,25 @@ isert_put_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
1637 struct isert_cmd, iscsi_cmd); 1733 struct isert_cmd, iscsi_cmd);
1638 struct isert_conn *isert_conn = (struct isert_conn *)conn->context; 1734 struct isert_conn *isert_conn = (struct isert_conn *)conn->context;
1639 struct ib_send_wr *send_wr = &isert_cmd->tx_desc.send_wr; 1735 struct ib_send_wr *send_wr = &isert_cmd->tx_desc.send_wr;
1736 struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
1737 struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1];
1738 struct iscsi_reject *hdr =
1739 (struct iscsi_reject *)&isert_cmd->tx_desc.iscsi_header;
1640 1740
1641 isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc); 1741 isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc);
1642 iscsit_build_reject(cmd, conn, (struct iscsi_reject *) 1742 iscsit_build_reject(cmd, conn, hdr);
1643 &isert_cmd->tx_desc.iscsi_header);
1644 isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc); 1743 isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc);
1744
1745 hton24(hdr->dlength, ISCSI_HDR_LEN);
1746 isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev,
1747 (void *)cmd->buf_ptr, ISCSI_HDR_LEN,
1748 DMA_TO_DEVICE);
1749 isert_cmd->pdu_buf_len = ISCSI_HDR_LEN;
1750 tx_dsg->addr = isert_cmd->pdu_buf_dma;
1751 tx_dsg->length = ISCSI_HDR_LEN;
1752 tx_dsg->lkey = isert_conn->conn_mr->lkey;
1753 isert_cmd->tx_desc.num_sge = 2;
1754
1645 isert_init_send_wr(isert_cmd, send_wr); 1755 isert_init_send_wr(isert_cmd, send_wr);
1646 1756
1647 pr_debug("Posting Reject IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); 1757 pr_debug("Posting Reject IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n");
@@ -1650,6 +1760,47 @@ isert_put_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
1650} 1760}
1651 1761
1652static int 1762static int
1763isert_put_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
1764{
1765 struct isert_cmd *isert_cmd = container_of(cmd,
1766 struct isert_cmd, iscsi_cmd);
1767 struct isert_conn *isert_conn = (struct isert_conn *)conn->context;
1768 struct ib_send_wr *send_wr = &isert_cmd->tx_desc.send_wr;
1769 struct iscsi_text_rsp *hdr =
1770 (struct iscsi_text_rsp *)&isert_cmd->tx_desc.iscsi_header;
1771 u32 txt_rsp_len;
1772 int rc;
1773
1774 isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc);
1775 rc = iscsit_build_text_rsp(cmd, conn, hdr);
1776 if (rc < 0)
1777 return rc;
1778
1779 txt_rsp_len = rc;
1780 isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc);
1781
1782 if (txt_rsp_len) {
1783 struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
1784 struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1];
1785 void *txt_rsp_buf = cmd->buf_ptr;
1786
1787 isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev,
1788 txt_rsp_buf, txt_rsp_len, DMA_TO_DEVICE);
1789
1790 isert_cmd->pdu_buf_len = txt_rsp_len;
1791 tx_dsg->addr = isert_cmd->pdu_buf_dma;
1792 tx_dsg->length = txt_rsp_len;
1793 tx_dsg->lkey = isert_conn->conn_mr->lkey;
1794 isert_cmd->tx_desc.num_sge = 2;
1795 }
1796 isert_init_send_wr(isert_cmd, send_wr);
1797
1798 pr_debug("Posting Text Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n");
1799
1800 return isert_post_response(isert_conn, isert_cmd);
1801}
1802
1803static int
1653isert_build_rdma_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, 1804isert_build_rdma_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
1654 struct ib_sge *ib_sge, struct ib_send_wr *send_wr, 1805 struct ib_sge *ib_sge, struct ib_send_wr *send_wr,
1655 u32 data_left, u32 offset) 1806 u32 data_left, u32 offset)
@@ -1947,6 +2098,9 @@ isert_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
1947 case ISTATE_SEND_REJECT: 2098 case ISTATE_SEND_REJECT:
1948 ret = isert_put_reject(cmd, conn); 2099 ret = isert_put_reject(cmd, conn);
1949 break; 2100 break;
2101 case ISTATE_SEND_TEXTRSP:
2102 ret = isert_put_text_rsp(cmd, conn);
2103 break;
1950 case ISTATE_SEND_STATUS: 2104 case ISTATE_SEND_STATUS:
1951 /* 2105 /*
1952 * Special case for sending non GOOD SCSI status from TX thread 2106 * Special case for sending non GOOD SCSI status from TX thread
@@ -2175,6 +2329,17 @@ isert_free_np(struct iscsi_np *np)
2175 kfree(isert_np); 2329 kfree(isert_np);
2176} 2330}
2177 2331
2332static int isert_check_state(struct isert_conn *isert_conn, int state)
2333{
2334 int ret;
2335
2336 mutex_lock(&isert_conn->conn_mutex);
2337 ret = (isert_conn->state == state);
2338 mutex_unlock(&isert_conn->conn_mutex);
2339
2340 return ret;
2341}
2342
2178static void isert_free_conn(struct iscsi_conn *conn) 2343static void isert_free_conn(struct iscsi_conn *conn)
2179{ 2344{
2180 struct isert_conn *isert_conn = conn->context; 2345 struct isert_conn *isert_conn = conn->context;
@@ -2184,26 +2349,43 @@ static void isert_free_conn(struct iscsi_conn *conn)
2184 * Decrement post_send_buf_count for special case when called 2349 * Decrement post_send_buf_count for special case when called
2185 * from isert_do_control_comp() -> iscsit_logout_post_handler() 2350 * from isert_do_control_comp() -> iscsit_logout_post_handler()
2186 */ 2351 */
2352 mutex_lock(&isert_conn->conn_mutex);
2187 if (isert_conn->logout_posted) 2353 if (isert_conn->logout_posted)
2188 atomic_dec(&isert_conn->post_send_buf_count); 2354 atomic_dec(&isert_conn->post_send_buf_count);
2189 2355
2190 if (isert_conn->conn_cm_id) 2356 if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) {
2357 pr_debug("Calling rdma_disconnect from isert_free_conn\n");
2191 rdma_disconnect(isert_conn->conn_cm_id); 2358 rdma_disconnect(isert_conn->conn_cm_id);
2359 }
2192 /* 2360 /*
2193 * Only wait for conn_wait_comp_err if the isert_conn made it 2361 * Only wait for conn_wait_comp_err if the isert_conn made it
2194 * into full feature phase.. 2362 * into full feature phase..
2195 */ 2363 */
2196 if (isert_conn->state > ISER_CONN_INIT) { 2364 if (isert_conn->state == ISER_CONN_UP) {
2197 pr_debug("isert_free_conn: Before wait_event comp_err %d\n", 2365 pr_debug("isert_free_conn: Before wait_event comp_err %d\n",
2198 isert_conn->state); 2366 isert_conn->state);
2367 mutex_unlock(&isert_conn->conn_mutex);
2368
2199 wait_event(isert_conn->conn_wait_comp_err, 2369 wait_event(isert_conn->conn_wait_comp_err,
2200 isert_conn->state == ISER_CONN_TERMINATING); 2370 (isert_check_state(isert_conn, ISER_CONN_TERMINATING)));
2201 pr_debug("isert_free_conn: After wait_event #1 >>>>>>>>>>>>\n"); 2371
2372 wait_event(isert_conn->conn_wait,
2373 (isert_check_state(isert_conn, ISER_CONN_DOWN)));
2374
2375 isert_put_conn(isert_conn);
2376 return;
2377 }
2378 if (isert_conn->state == ISER_CONN_INIT) {
2379 mutex_unlock(&isert_conn->conn_mutex);
2380 isert_put_conn(isert_conn);
2381 return;
2202 } 2382 }
2383 pr_debug("isert_free_conn: wait_event conn_wait %d\n",
2384 isert_conn->state);
2385 mutex_unlock(&isert_conn->conn_mutex);
2203 2386
2204 pr_debug("isert_free_conn: wait_event conn_wait %d\n", isert_conn->state); 2387 wait_event(isert_conn->conn_wait,
2205 wait_event(isert_conn->conn_wait, isert_conn->state == ISER_CONN_DOWN); 2388 (isert_check_state(isert_conn, ISER_CONN_DOWN)));
2206 pr_debug("isert_free_conn: After wait_event #2 >>>>>>>>>>>>>>>>>>>>\n");
2207 2389
2208 isert_put_conn(isert_conn); 2390 isert_put_conn(isert_conn);
2209} 2391}
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h
index b104f4c2cd38..191117b5b508 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.h
+++ b/drivers/infiniband/ulp/isert/ib_isert.h
@@ -61,8 +61,8 @@ struct isert_cmd {
61 uint32_t write_stag; 61 uint32_t write_stag;
62 uint64_t read_va; 62 uint64_t read_va;
63 uint64_t write_va; 63 uint64_t write_va;
64 u64 sense_buf_dma; 64 u64 pdu_buf_dma;
65 u32 sense_buf_len; 65 u32 pdu_buf_len;
66 u32 read_va_off; 66 u32 read_va_off;
67 u32 write_va_off; 67 u32 write_va_off;
68 u32 rdma_wr_num; 68 u32 rdma_wr_num;
@@ -102,6 +102,7 @@ struct isert_conn {
102 struct ib_qp *conn_qp; 102 struct ib_qp *conn_qp;
103 struct isert_device *conn_device; 103 struct isert_device *conn_device;
104 struct work_struct conn_logout_work; 104 struct work_struct conn_logout_work;
105 struct mutex conn_mutex;
105 wait_queue_head_t conn_wait; 106 wait_queue_head_t conn_wait;
106 wait_queue_head_t conn_wait_comp_err; 107 wait_queue_head_t conn_wait_comp_err;
107 struct kref conn_kref; 108 struct kref conn_kref;