aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2007-05-30 13:57:14 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2007-06-01 12:57:17 -0400
commitd473cc7f15f64ab8a90c3d7288ef30f46785d8d5 (patch)
treebef7d5c01842430fcd93f6a235ad404d1de1f5a3 /drivers
parent8ad5781ae9702a8f95cfdf30967752e4297613ee (diff)
[SCSI] iscsi: Some fixes in preparation for bidirectional support - exp_datasn
This patch fixes handling of expected datasn/r2tsn as received from target. It is done according to: T10 rfc3720 section 3.2.2.3. Data Sequencing. . unify expected datasn/r2tsn into one counter . calculate than check expected datasn/r2tsn. On error print a message and fail the request. (TODO use iscsi retransmits) . remove the FIXME ;) . avoid zero length memset Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/iscsi_tcp.c18
-rw-r--r--drivers/scsi/iscsi_tcp.h2
-rw-r--r--drivers/scsi/libiscsi.c5
3 files changed, 15 insertions, 10 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 8201e6c4d8a9..17fc79c408a2 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -229,10 +229,13 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
229 if (tcp_conn->in.datalen == 0) 229 if (tcp_conn->in.datalen == 0)
230 return 0; 230 return 0;
231 231
232 if (ctask->datasn != datasn) 232 if (tcp_ctask->exp_datasn != datasn) {
233 debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->datasn(%d)\n",
234 __FUNCTION__, tcp_ctask->exp_datasn, datasn);
233 return ISCSI_ERR_DATASN; 235 return ISCSI_ERR_DATASN;
236 }
234 237
235 ctask->datasn++; 238 tcp_ctask->exp_datasn++;
236 239
237 tcp_ctask->data_offset = be32_to_cpu(rhdr->offset); 240 tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
238 if (tcp_ctask->data_offset + tcp_conn->in.datalen > ctask->total_length) 241 if (tcp_ctask->data_offset + tcp_conn->in.datalen > ctask->total_length)
@@ -365,15 +368,16 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
365 return ISCSI_ERR_DATALEN; 368 return ISCSI_ERR_DATALEN;
366 } 369 }
367 370
368 if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn) 371 if (tcp_ctask->exp_datasn != r2tsn){
372 debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
373 __FUNCTION__, tcp_ctask->exp_datasn, r2tsn);
369 return ISCSI_ERR_R2TSN; 374 return ISCSI_ERR_R2TSN;
375 }
370 376
371 rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr); 377 rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
372 if (rc) 378 if (rc)
373 return rc; 379 return rc;
374 380
375 /* FIXME: use R2TSN to detect missing R2T */
376
377 /* fill-in new R2T associated with the task */ 381 /* fill-in new R2T associated with the task */
378 spin_lock(&session->lock); 382 spin_lock(&session->lock);
379 if (!ctask->sc || ctask->mtask || 383 if (!ctask->sc || ctask->mtask ||
@@ -414,7 +418,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
414 418
415 iscsi_solicit_data_init(conn, ctask, r2t); 419 iscsi_solicit_data_init(conn, ctask, r2t);
416 420
417 tcp_ctask->exp_r2tsn = r2tsn + 1; 421 tcp_ctask->exp_datasn = r2tsn + 1;
418 __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); 422 __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
419 tcp_ctask->xmstate |= XMSTATE_SOL_HDR; 423 tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
420 list_move_tail(&ctask->running, &conn->xmitqueue); 424 list_move_tail(&ctask->running, &conn->xmitqueue);
@@ -1284,10 +1288,10 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1284 1288
1285 tcp_ctask->sent = 0; 1289 tcp_ctask->sent = 0;
1286 tcp_ctask->sg_count = 0; 1290 tcp_ctask->sg_count = 0;
1291 tcp_ctask->exp_datasn = 0;
1287 1292
1288 if (sc->sc_data_direction == DMA_TO_DEVICE) { 1293 if (sc->sc_data_direction == DMA_TO_DEVICE) {
1289 tcp_ctask->xmstate = XMSTATE_W_HDR; 1294 tcp_ctask->xmstate = XMSTATE_W_HDR;
1290 tcp_ctask->exp_r2tsn = 0;
1291 BUG_ON(ctask->total_length == 0); 1295 BUG_ON(ctask->total_length == 0);
1292 1296
1293 if (sc->use_sg) { 1297 if (sc->use_sg) {
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index 32736831790e..f909edbf61ee 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -152,7 +152,7 @@ struct iscsi_tcp_cmd_task {
152 struct scatterlist *sg; /* per-cmd SG list */ 152 struct scatterlist *sg; /* per-cmd SG list */
153 struct scatterlist *bad_sg; /* assert statement */ 153 struct scatterlist *bad_sg; /* assert statement */
154 int sg_count; /* SG's to process */ 154 int sg_count; /* SG's to process */
155 uint32_t exp_r2tsn; 155 uint32_t exp_datasn; /* expected target's R2TSN/DataSN */
156 int data_offset; 156 int data_offset;
157 struct iscsi_r2t_info *r2t; /* in progress R2T */ 157 struct iscsi_r2t_info *r2t; /* in progress R2T */
158 struct iscsi_queue r2tpool; 158 struct iscsi_queue r2tpool;
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 5e6a42429c39..eb5113607958 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -120,7 +120,9 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
120 session->cmdsn++; 120 session->cmdsn++;
121 hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); 121 hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
122 memcpy(hdr->cdb, sc->cmnd, sc->cmd_len); 122 memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
123 memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len); 123 if (sc->cmd_len < MAX_COMMAND_SIZE)
124 memset(&hdr->cdb[sc->cmd_len], 0,
125 MAX_COMMAND_SIZE - sc->cmd_len);
124 126
125 ctask->data_count = 0; 127 ctask->data_count = 0;
126 if (sc->sc_data_direction == DMA_TO_DEVICE) { 128 if (sc->sc_data_direction == DMA_TO_DEVICE) {
@@ -165,7 +167,6 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
165 /* No unsolicit Data-Out's */ 167 /* No unsolicit Data-Out's */
166 ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL; 168 ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL;
167 } else { 169 } else {
168 ctask->datasn = 0;
169 hdr->flags |= ISCSI_FLAG_CMD_FINAL; 170 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
170 zero_data(hdr->dlength); 171 zero_data(hdr->dlength);
171 172