aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/isert/ib_isert.c
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2013-06-14 19:47:15 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2013-07-07 21:36:48 -0400
commitadb54c29310e8785e4f2eb0dc76e0e2fde943b11 (patch)
treea1741996414a81337ffccc8e56ff6dbca8b7c1d6 /drivers/infiniband/ulp/isert/ib_isert.c
parentdbbc5d11074fc017488e6bdaaf9238d53e35ab07 (diff)
iser-target: Add support for ISCSI_OP_TEXT opcode + payload handling
This patch adds isert_handle_text_cmd() to handle incoming ISCSI_OP_TEXT PDU processing, along with isert_put_text_rsp() for posting ISCSI_OP_TEXT_RSP ib_send_wr response. It copies ISCSI_OP_TEXT payload using unsolicited payload at &iser_rx_desc->data[0] into iscsi_cmd->text_in_ptr for usage with outgoing isert_put_text_rsp() -> iscsit_build_text_rsp() v2 changes: - Let iscsit_build_text_rsp() determine any extra padding Reported-by: Or Gerlitz <ogerlitz@mellanox.com> Cc: Or Gerlitz <ogerlitz@mellanox.com> Cc: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/infiniband/ulp/isert/ib_isert.c')
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c89
1 files changed, 88 insertions, 1 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index fa4251803577..f02bfcc282e5 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -1033,6 +1033,33 @@ isert_handle_nop_out(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
1033} 1033}
1034 1034
1035static int 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
1036isert_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,
1037 uint32_t read_stag, uint64_t read_va, 1064 uint32_t read_stag, uint64_t read_va,
1038 uint32_t write_stag, uint64_t write_va) 1065 uint32_t write_stag, uint64_t write_va)
@@ -1091,6 +1118,15 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
1091 SECONDS_FOR_LOGOUT_COMP * 1118 SECONDS_FOR_LOGOUT_COMP *
1092 HZ); 1119 HZ);
1093 break; 1120 break;
1121 case ISCSI_OP_TEXT:
1122 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
1123 if (!cmd)
1124 break;
1125
1126 isert_cmd = container_of(cmd, struct isert_cmd, iscsi_cmd);
1127 ret = isert_handle_text_cmd(isert_conn, isert_cmd,
1128 rx_desc, (struct iscsi_text *)hdr);
1129 break;
1094 default: 1130 default:
1095 pr_err("Got unknown iSCSI OpCode: 0x%02x\n", opcode); 1131 pr_err("Got unknown iSCSI OpCode: 0x%02x\n", opcode);
1096 dump_stack(); 1132 dump_stack();
@@ -1245,6 +1281,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd)
1245 break; 1281 break;
1246 case ISCSI_OP_REJECT: 1282 case ISCSI_OP_REJECT:
1247 case ISCSI_OP_NOOP_OUT: 1283 case ISCSI_OP_NOOP_OUT:
1284 case ISCSI_OP_TEXT:
1248 spin_lock_bh(&conn->cmd_lock); 1285 spin_lock_bh(&conn->cmd_lock);
1249 if (!list_empty(&cmd->i_conn_node)) 1286 if (!list_empty(&cmd->i_conn_node))
1250 list_del(&cmd->i_conn_node); 1287 list_del(&cmd->i_conn_node);
@@ -1366,6 +1403,11 @@ isert_do_control_comp(struct work_struct *work)
1366 isert_conn->logout_posted = true; 1403 isert_conn->logout_posted = true;
1367 iscsit_logout_post_handler(cmd, cmd->conn); 1404 iscsit_logout_post_handler(cmd, cmd->conn);
1368 break; 1405 break;
1406 case ISTATE_SEND_TEXTRSP:
1407 atomic_dec(&isert_conn->post_send_buf_count);
1408 cmd->i_state = ISTATE_SENT_STATUS;
1409 isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
1410 break;
1369 default: 1411 default:
1370 pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state); 1412 pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state);
1371 dump_stack(); 1413 dump_stack();
@@ -1383,7 +1425,8 @@ isert_response_completion(struct iser_tx_desc *tx_desc,
1383 1425
1384 if (cmd->i_state == ISTATE_SEND_TASKMGTRSP || 1426 if (cmd->i_state == ISTATE_SEND_TASKMGTRSP ||
1385 cmd->i_state == ISTATE_SEND_LOGOUTRSP || 1427 cmd->i_state == ISTATE_SEND_LOGOUTRSP ||
1386 cmd->i_state == ISTATE_SEND_REJECT) { 1428 cmd->i_state == ISTATE_SEND_REJECT ||
1429 cmd->i_state == ISTATE_SEND_TEXTRSP) {
1387 isert_unmap_tx_desc(tx_desc, ib_dev); 1430 isert_unmap_tx_desc(tx_desc, ib_dev);
1388 1431
1389 INIT_WORK(&isert_cmd->comp_work, isert_do_control_comp); 1432 INIT_WORK(&isert_cmd->comp_work, isert_do_control_comp);
@@ -1709,6 +1752,47 @@ isert_put_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
1709} 1752}
1710 1753
1711static int 1754static int
1755isert_put_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
1756{
1757 struct isert_cmd *isert_cmd = container_of(cmd,
1758 struct isert_cmd, iscsi_cmd);
1759 struct isert_conn *isert_conn = (struct isert_conn *)conn->context;
1760 struct ib_send_wr *send_wr = &isert_cmd->tx_desc.send_wr;
1761 struct iscsi_text_rsp *hdr =
1762 (struct iscsi_text_rsp *)&isert_cmd->tx_desc.iscsi_header;
1763 u32 txt_rsp_len;
1764 int rc;
1765
1766 isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc);
1767 rc = iscsit_build_text_rsp(cmd, conn, hdr);
1768 if (rc < 0)
1769 return rc;
1770
1771 txt_rsp_len = rc;
1772 isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc);
1773
1774 if (txt_rsp_len) {
1775 struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
1776 struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1];
1777 void *txt_rsp_buf = cmd->buf_ptr;
1778
1779 isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev,
1780 txt_rsp_buf, txt_rsp_len, DMA_TO_DEVICE);
1781
1782 isert_cmd->pdu_buf_len = txt_rsp_len;
1783 tx_dsg->addr = isert_cmd->pdu_buf_dma;
1784 tx_dsg->length = txt_rsp_len;
1785 tx_dsg->lkey = isert_conn->conn_mr->lkey;
1786 isert_cmd->tx_desc.num_sge = 2;
1787 }
1788 isert_init_send_wr(isert_cmd, send_wr);
1789
1790 pr_debug("Posting Text Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n");
1791
1792 return isert_post_response(isert_conn, isert_cmd);
1793}
1794
1795static int
1712isert_build_rdma_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, 1796isert_build_rdma_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
1713 struct ib_sge *ib_sge, struct ib_send_wr *send_wr, 1797 struct ib_sge *ib_sge, struct ib_send_wr *send_wr,
1714 u32 data_left, u32 offset) 1798 u32 data_left, u32 offset)
@@ -2006,6 +2090,9 @@ isert_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
2006 case ISTATE_SEND_REJECT: 2090 case ISTATE_SEND_REJECT:
2007 ret = isert_put_reject(cmd, conn); 2091 ret = isert_put_reject(cmd, conn);
2008 break; 2092 break;
2093 case ISTATE_SEND_TEXTRSP:
2094 ret = isert_put_text_rsp(cmd, conn);
2095 break;
2009 case ISTATE_SEND_STATUS: 2096 case ISTATE_SEND_STATUS:
2010 /* 2097 /*
2011 * Special case for sending non GOOD SCSI status from TX thread 2098 * Special case for sending non GOOD SCSI status from TX thread