aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c18
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h1
-rw-r--r--drivers/scsi/iscsi_tcp.c30
-rw-r--r--drivers/scsi/iscsi_tcp.h1
-rw-r--r--drivers/scsi/libiscsi.c25
-rw-r--r--include/scsi/libiscsi.h5
6 files changed, 31 insertions, 49 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 1437d7ee3b19..101e407eaa43 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -141,18 +141,11 @@ iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask)
141 141
142 if (sc->sc_data_direction == DMA_TO_DEVICE) { 142 if (sc->sc_data_direction == DMA_TO_DEVICE) {
143 BUG_ON(ctask->total_length == 0); 143 BUG_ON(ctask->total_length == 0);
144 /* bytes to be sent via RDMA operations */
145 iser_ctask->rdma_data_count = ctask->total_length -
146 ctask->imm_count -
147 ctask->unsol_count;
148 144
149 debug_scsi("cmd [itt %x total %d imm %d unsol_data %d " 145 debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
150 "rdma_data %d]\n",
151 ctask->itt, ctask->total_length, ctask->imm_count, 146 ctask->itt, ctask->total_length, ctask->imm_count,
152 ctask->unsol_count, iser_ctask->rdma_data_count); 147 ctask->unsol_count);
153 } else 148 }
154 /* bytes to be sent via RDMA operations */
155 iser_ctask->rdma_data_count = ctask->total_length;
156 149
157 iser_ctask_rdma_init(iser_ctask); 150 iser_ctask_rdma_init(iser_ctask);
158} 151}
@@ -196,13 +189,10 @@ iscsi_iser_ctask_xmit_unsol_data(struct iscsi_conn *conn,
196{ 189{
197 struct iscsi_data hdr; 190 struct iscsi_data hdr;
198 int error = 0; 191 int error = 0;
199 struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
200 192
201 /* Send data-out PDUs while there's still unsolicited data to send */ 193 /* Send data-out PDUs while there's still unsolicited data to send */
202 while (ctask->unsol_count > 0) { 194 while (ctask->unsol_count > 0) {
203 iscsi_prep_unsolicit_data_pdu(ctask, &hdr, 195 iscsi_prep_unsolicit_data_pdu(ctask, &hdr);
204 iser_ctask->rdma_data_count);
205
206 debug_scsi("Sending data-out: itt 0x%x, data count %d\n", 196 debug_scsi("Sending data-out: itt 0x%x, data count %d\n",
207 hdr.itt, ctask->data_count); 197 hdr.itt, ctask->data_count);
208 198
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 3350ba690cfe..7c3d0c96d889 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -257,7 +257,6 @@ struct iscsi_iser_conn {
257struct iscsi_iser_cmd_task { 257struct iscsi_iser_cmd_task {
258 struct iser_desc desc; 258 struct iser_desc desc;
259 struct iscsi_iser_conn *iser_conn; 259 struct iscsi_iser_conn *iser_conn;
260 int rdma_data_count;/* RDMA bytes */
261 enum iser_task_status status; 260 enum iser_task_status status;
262 int command_sent; /* set if command sent */ 261 int command_sent; /* set if command sent */
263 int dir[ISER_DIRS_NUM]; /* set if dir use*/ 262 int dir[ISER_DIRS_NUM]; /* set if dir use*/
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 058f094f945a..a97a3a4e99eb 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -1264,19 +1264,6 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1264 r2t->data_count); 1264 r2t->data_count);
1265} 1265}
1266 1266
1267static void
1268iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1269{
1270 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1271 struct iscsi_data_task *dtask;
1272
1273 dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask;
1274 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr,
1275 tcp_ctask->r2t_data_count);
1276 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr,
1277 sizeof(struct iscsi_hdr));
1278}
1279
1280/** 1267/**
1281 * iscsi_tcp_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands 1268 * iscsi_tcp_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
1282 * @conn: iscsi connection 1269 * @conn: iscsi connection
@@ -1326,14 +1313,11 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1326 if (ctask->unsol_count) 1313 if (ctask->unsol_count)
1327 tcp_ctask->xmstate |= XMSTATE_UNS_HDR | 1314 tcp_ctask->xmstate |= XMSTATE_UNS_HDR |
1328 XMSTATE_UNS_INIT; 1315 XMSTATE_UNS_INIT;
1329 tcp_ctask->r2t_data_count = ctask->total_length -
1330 ctask->imm_count -
1331 ctask->unsol_count;
1332 1316
1333 debug_scsi("cmd [itt 0x%x total %d imm %d imm_data %d " 1317 debug_scsi("cmd [itt 0x%x total %d imm_data %d "
1334 "r2t_data %d]\n", 1318 "unsol count %d, unsol offset %d]\n",
1335 ctask->itt, ctask->total_length, ctask->imm_count, 1319 ctask->itt, ctask->total_length, ctask->imm_count,
1336 ctask->unsol_count, tcp_ctask->r2t_data_count); 1320 ctask->unsol_count, ctask->unsol_offset);
1337 } else 1321 } else
1338 tcp_ctask->xmstate = XMSTATE_R_HDR; 1322 tcp_ctask->xmstate = XMSTATE_R_HDR;
1339 1323
@@ -1531,8 +1515,10 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1531 1515
1532 tcp_ctask->xmstate |= XMSTATE_UNS_DATA; 1516 tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
1533 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { 1517 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) {
1534 iscsi_unsolicit_data_init(conn, ctask); 1518 dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask;
1535 dtask = tcp_ctask->dtask; 1519 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr);
1520 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr,
1521 sizeof(struct iscsi_hdr));
1536 if (conn->hdrdgst_en) 1522 if (conn->hdrdgst_en)
1537 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1523 iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
1538 (u8*)dtask->hdrext); 1524 (u8*)dtask->hdrext);
@@ -1720,7 +1706,6 @@ data_out_done:
1720 * Done with this R2T. Check if there are more 1706 * Done with this R2T. Check if there are more
1721 * outstanding R2Ts ready to be processed. 1707 * outstanding R2Ts ready to be processed.
1722 */ 1708 */
1723 BUG_ON(tcp_ctask->r2t_data_count - r2t->data_length < 0);
1724 if (conn->datadgst_en) { 1709 if (conn->datadgst_en) {
1725 rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, 1710 rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf,
1726 &dtask->digest, 1); 1711 &dtask->digest, 1);
@@ -1732,7 +1717,6 @@ data_out_done:
1732 debug_tcp("r2t done dout digest 0x%x\n", dtask->digest); 1717 debug_tcp("r2t done dout digest 0x%x\n", dtask->digest);
1733 } 1718 }
1734 1719
1735 tcp_ctask->r2t_data_count -= r2t->data_length;
1736 tcp_ctask->r2t = NULL; 1720 tcp_ctask->r2t = NULL;
1737 spin_lock_bh(&session->lock); 1721 spin_lock_bh(&session->lock);
1738 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); 1722 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index 6a4ee704e46e..aace8f70dfd7 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -157,7 +157,6 @@ struct iscsi_tcp_cmd_task {
157 struct scatterlist *bad_sg; /* assert statement */ 157 struct scatterlist *bad_sg; /* assert statement */
158 int sg_count; /* SG's to process */ 158 int sg_count; /* SG's to process */
159 uint32_t exp_r2tsn; 159 uint32_t exp_r2tsn;
160 int r2t_data_count; /* R2T Data-Out bytes */
161 int data_offset; 160 int data_offset;
162 struct iscsi_r2t_info *r2t; /* in progress R2T */ 161 struct iscsi_r2t_info *r2t; /* in progress R2T */
163 struct iscsi_queue r2tpool; 162 struct iscsi_queue r2tpool;
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 5884cd26d53a..a7c6e70f4ef8 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -68,8 +68,7 @@ iscsi_check_assign_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
68EXPORT_SYMBOL_GPL(iscsi_check_assign_cmdsn); 68EXPORT_SYMBOL_GPL(iscsi_check_assign_cmdsn);
69 69
70void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask, 70void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask,
71 struct iscsi_data *hdr, 71 struct iscsi_data *hdr)
72 int transport_data_cnt)
73{ 72{
74 struct iscsi_conn *conn = ctask->conn; 73 struct iscsi_conn *conn = ctask->conn;
75 74
@@ -82,14 +81,12 @@ void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask,
82 81
83 hdr->itt = ctask->hdr->itt; 82 hdr->itt = ctask->hdr->itt;
84 hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); 83 hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
85 84 hdr->offset = cpu_to_be32(ctask->unsol_offset);
86 hdr->offset = cpu_to_be32(ctask->total_length -
87 transport_data_cnt -
88 ctask->unsol_count);
89 85
90 if (ctask->unsol_count > conn->max_xmit_dlength) { 86 if (ctask->unsol_count > conn->max_xmit_dlength) {
91 hton24(hdr->dlength, conn->max_xmit_dlength); 87 hton24(hdr->dlength, conn->max_xmit_dlength);
92 ctask->data_count = conn->max_xmit_dlength; 88 ctask->data_count = conn->max_xmit_dlength;
89 ctask->unsol_offset += ctask->data_count;
93 hdr->flags = 0; 90 hdr->flags = 0;
94 } else { 91 } else {
95 hton24(hdr->dlength, ctask->unsol_count); 92 hton24(hdr->dlength, ctask->unsol_count);
@@ -125,6 +122,7 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
125 memcpy(hdr->cdb, sc->cmnd, sc->cmd_len); 122 memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
126 memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len); 123 memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len);
127 124
125 ctask->data_count = 0;
128 if (sc->sc_data_direction == DMA_TO_DEVICE) { 126 if (sc->sc_data_direction == DMA_TO_DEVICE) {
129 hdr->flags |= ISCSI_FLAG_CMD_WRITE; 127 hdr->flags |= ISCSI_FLAG_CMD_WRITE;
130 /* 128 /*
@@ -143,6 +141,7 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
143 */ 141 */
144 ctask->imm_count = 0; 142 ctask->imm_count = 0;
145 ctask->unsol_count = 0; 143 ctask->unsol_count = 0;
144 ctask->unsol_offset = 0;
146 ctask->unsol_datasn = 0; 145 ctask->unsol_datasn = 0;
147 146
148 if (session->imm_data_en) { 147 if (session->imm_data_en) {
@@ -156,9 +155,12 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
156 } else 155 } else
157 zero_data(ctask->hdr->dlength); 156 zero_data(ctask->hdr->dlength);
158 157
159 if (!session->initial_r2t_en) 158 if (!session->initial_r2t_en) {
160 ctask->unsol_count = min(session->first_burst, 159 ctask->unsol_count = min(session->first_burst,
161 ctask->total_length) - ctask->imm_count; 160 ctask->total_length) - ctask->imm_count;
161 ctask->unsol_offset = ctask->imm_count;
162 }
163
162 if (!ctask->unsol_count) 164 if (!ctask->unsol_count)
163 /* No unsolicit Data-Out's */ 165 /* No unsolicit Data-Out's */
164 ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL; 166 ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL;
@@ -1520,11 +1522,18 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
1520 struct iscsi_conn *conn = cls_conn->dd_data; 1522 struct iscsi_conn *conn = cls_conn->dd_data;
1521 struct iscsi_session *session = conn->session; 1523 struct iscsi_session *session = conn->session;
1522 1524
1523 if (session == NULL) { 1525 if (!session) {
1524 printk(KERN_ERR "iscsi: can't start unbound connection\n"); 1526 printk(KERN_ERR "iscsi: can't start unbound connection\n");
1525 return -EPERM; 1527 return -EPERM;
1526 } 1528 }
1527 1529
1530 if (session->first_burst > session->max_burst) {
1531 printk("iscsi: invalid burst lengths: "
1532 "first_burst %d max_burst %d\n",
1533 session->first_burst, session->max_burst);
1534 return -EINVAL;
1535 }
1536
1528 spin_lock_bh(&session->lock); 1537 spin_lock_bh(&session->lock);
1529 conn->c_stage = ISCSI_CONN_STARTED; 1538 conn->c_stage = ISCSI_CONN_STARTED;
1530 session->state = ISCSI_STATE_LOGGED_IN; 1539 session->state = ISCSI_STATE_LOGGED_IN;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 41904f611d12..4900650bd081 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -102,6 +102,8 @@ struct iscsi_cmd_task {
102 uint32_t unsol_datasn; 102 uint32_t unsol_datasn;
103 int imm_count; /* imm-data (bytes) */ 103 int imm_count; /* imm-data (bytes) */
104 int unsol_count; /* unsolicited (bytes)*/ 104 int unsol_count; /* unsolicited (bytes)*/
105 /* offset in unsolicited stream (bytes); */
106 int unsol_offset;
105 int data_count; /* remaining Data-Out */ 107 int data_count; /* remaining Data-Out */
106 struct scsi_cmnd *sc; /* associated SCSI cmd*/ 108 struct scsi_cmnd *sc; /* associated SCSI cmd*/
107 int total_length; 109 int total_length;
@@ -290,8 +292,7 @@ extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
290extern int iscsi_check_assign_cmdsn(struct iscsi_session *, 292extern int iscsi_check_assign_cmdsn(struct iscsi_session *,
291 struct iscsi_nopin *); 293 struct iscsi_nopin *);
292extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *, 294extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *,
293 struct iscsi_data *hdr, 295 struct iscsi_data *hdr);
294 int transport_data_cnt);
295extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, 296extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
296 char *, uint32_t); 297 char *, uint32_t);
297extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, 298extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,