1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <asm/unaligned.h>
22#include <scsi/iscsi_proto.h>
23#include <target/target_core_base.h>
24#include <target/target_core_fabric.h>
25
26#include "iscsi_target_core.h"
27#include "iscsi_target_seq_pdu_list.h"
28#include "iscsi_target_datain_values.h"
29#include "iscsi_target_device.h"
30#include "iscsi_target_erl0.h"
31#include "iscsi_target_erl1.h"
32#include "iscsi_target_erl2.h"
33#include "iscsi_target_tmr.h"
34#include "iscsi_target_tpg.h"
35#include "iscsi_target_util.h"
36#include "iscsi_target.h"
37
38u8 iscsit_tmr_abort_task(
39 struct iscsi_cmd *cmd,
40 unsigned char *buf)
41{
42 struct iscsi_cmd *ref_cmd;
43 struct iscsi_conn *conn = cmd->conn;
44 struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
45 struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
46 struct iscsi_tm *hdr = (struct iscsi_tm *) buf;
47
48 ref_cmd = iscsit_find_cmd_from_itt(conn, hdr->rtt);
49 if (!ref_cmd) {
50 pr_err("Unable to locate RefTaskTag: 0x%08x on CID:"
51 " %hu.\n", hdr->rtt, conn->cid);
52 return ((hdr->refcmdsn >= conn->sess->exp_cmd_sn) &&
53 (hdr->refcmdsn <= conn->sess->max_cmd_sn)) ?
54 ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK;
55 }
56 if (ref_cmd->cmd_sn != hdr->refcmdsn) {
57 pr_err("RefCmdSN 0x%08x does not equal"
58 " task's CmdSN 0x%08x. Rejecting ABORT_TASK.\n",
59 hdr->refcmdsn, ref_cmd->cmd_sn);
60 return ISCSI_TMF_RSP_REJECTED;
61 }
62
63 se_tmr->ref_task_tag = hdr->rtt;
64 se_tmr->ref_cmd = &ref_cmd->se_cmd;
65 tmr_req->ref_cmd_sn = hdr->refcmdsn;
66 tmr_req->exp_data_sn = hdr->exp_datasn;
67
68 return ISCSI_TMF_RSP_COMPLETE;
69}
70
71
72
73
74int iscsit_tmr_task_warm_reset(
75 struct iscsi_conn *conn,
76 struct iscsi_tmr_req *tmr_req,
77 unsigned char *buf)
78{
79 struct iscsi_session *sess = conn->sess;
80 struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
81#if 0
82 struct iscsi_init_task_mgt_cmnd *hdr =
83 (struct iscsi_init_task_mgt_cmnd *) buf;
84#endif
85 if (!na->tmr_warm_reset) {
86 pr_err("TMR Opcode TARGET_WARM_RESET authorization"
87 " failed for Initiator Node: %s\n",
88 sess->se_sess->se_node_acl->initiatorname);
89 return -1;
90 }
91
92
93
94 return 0;
95}
96
97int iscsit_tmr_task_cold_reset(
98 struct iscsi_conn *conn,
99 struct iscsi_tmr_req *tmr_req,
100 unsigned char *buf)
101{
102 struct iscsi_session *sess = conn->sess;
103 struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
104
105 if (!na->tmr_cold_reset) {
106 pr_err("TMR Opcode TARGET_COLD_RESET authorization"
107 " failed for Initiator Node: %s\n",
108 sess->se_sess->se_node_acl->initiatorname);
109 return -1;
110 }
111
112
113
114 return 0;
115}
116
117u8 iscsit_tmr_task_reassign(
118 struct iscsi_cmd *cmd,
119 unsigned char *buf)
120{
121 struct iscsi_cmd *ref_cmd = NULL;
122 struct iscsi_conn *conn = cmd->conn;
123 struct iscsi_conn_recovery *cr = NULL;
124 struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
125 struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
126 struct iscsi_tm *hdr = (struct iscsi_tm *) buf;
127 int ret;
128
129 pr_debug("Got TASK_REASSIGN TMR ITT: 0x%08x,"
130 " RefTaskTag: 0x%08x, ExpDataSN: 0x%08x, CID: %hu\n",
131 hdr->itt, hdr->rtt, hdr->exp_datasn, conn->cid);
132
133 if (conn->sess->sess_ops->ErrorRecoveryLevel != 2) {
134 pr_err("TMR TASK_REASSIGN not supported in ERL<2,"
135 " ignoring request.\n");
136 return ISCSI_TMF_RSP_NOT_SUPPORTED;
137 }
138
139 ret = iscsit_find_cmd_for_recovery(conn->sess, &ref_cmd, &cr, hdr->rtt);
140 if (ret == -2) {
141 pr_err("Command ITT: 0x%08x is still alligent to CID:"
142 " %hu\n", ref_cmd->init_task_tag, cr->cid);
143 return ISCSI_TMF_RSP_TASK_ALLEGIANT;
144 } else if (ret == -1) {
145 pr_err("Unable to locate RefTaskTag: 0x%08x in"
146 " connection recovery command list.\n", hdr->rtt);
147 return ISCSI_TMF_RSP_NO_TASK;
148 }
149
150
151
152
153 if (cr->maxrecvdatasegmentlength !=
154 conn->conn_ops->MaxRecvDataSegmentLength) {
155 pr_err("Unable to perform connection recovery for"
156 " differing MaxRecvDataSegmentLength, rejecting"
157 " TMR TASK_REASSIGN.\n");
158 return ISCSI_TMF_RSP_REJECTED;
159 }
160
161 se_tmr->ref_task_tag = hdr->rtt;
162 se_tmr->ref_cmd = &ref_cmd->se_cmd;
163 se_tmr->ref_task_lun = get_unaligned_le64(&hdr->lun);
164 tmr_req->ref_cmd_sn = hdr->refcmdsn;
165 tmr_req->exp_data_sn = hdr->exp_datasn;
166 tmr_req->conn_recovery = cr;
167 tmr_req->task_reassign = 1;
168
169
170
171
172
173 return ISCSI_TMF_RSP_COMPLETE;
174}
175
176static void iscsit_task_reassign_remove_cmd(
177 struct iscsi_cmd *cmd,
178 struct iscsi_conn_recovery *cr,
179 struct iscsi_session *sess)
180{
181 int ret;
182
183 spin_lock(&cr->conn_recovery_cmd_lock);
184 ret = iscsit_remove_cmd_from_connection_recovery(cmd, sess);
185 spin_unlock(&cr->conn_recovery_cmd_lock);
186 if (!ret) {
187 pr_debug("iSCSI connection recovery successful for CID:"
188 " %hu on SID: %u\n", cr->cid, sess->sid);
189 iscsit_remove_active_connection_recovery_entry(cr, sess);
190 }
191}
192
193static int iscsit_task_reassign_complete_nop_out(
194 struct iscsi_tmr_req *tmr_req,
195 struct iscsi_conn *conn)
196{
197 struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
198 struct se_cmd *se_cmd = se_tmr->ref_cmd;
199 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
200 struct iscsi_conn_recovery *cr;
201
202 if (!cmd->cr) {
203 pr_err("struct iscsi_conn_recovery pointer for ITT: 0x%08x"
204 " is NULL!\n", cmd->init_task_tag);
205 return -1;
206 }
207 cr = cmd->cr;
208
209
210
211
212
213
214 cmd->stat_sn = cmd->exp_stat_sn = 0;
215
216 iscsit_task_reassign_remove_cmd(cmd, cr, conn->sess);
217
218 spin_lock_bh(&conn->cmd_lock);
219 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
220 spin_unlock_bh(&conn->cmd_lock);
221
222 cmd->i_state = ISTATE_SEND_NOPIN;
223 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
224 return 0;
225}
226
227static int iscsit_task_reassign_complete_write(
228 struct iscsi_cmd *cmd,
229 struct iscsi_tmr_req *tmr_req)
230{
231 int no_build_r2ts = 0;
232 u32 length = 0, offset = 0;
233 struct iscsi_conn *conn = cmd->conn;
234 struct se_cmd *se_cmd = &cmd->se_cmd;
235
236
237
238
239 if (!tmr_req->exp_data_sn) {
240 cmd->cmd_flags &= ~ICF_GOT_DATACK_SNACK;
241 cmd->acked_data_sn = 0;
242 } else {
243 cmd->cmd_flags |= ICF_GOT_DATACK_SNACK;
244 cmd->acked_data_sn = (tmr_req->exp_data_sn - 1);
245 }
246
247
248
249
250
251
252 if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) {
253 if (!atomic_read(&cmd->se_cmd.t_transport_sent)) {
254 pr_debug("WRITE ITT: 0x%08x: t_state: %d"
255 " never sent to transport\n",
256 cmd->init_task_tag, cmd->se_cmd.t_state);
257 return transport_generic_handle_data(se_cmd);
258 }
259
260 cmd->i_state = ISTATE_SEND_STATUS;
261 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
262 return 0;
263 }
264
265
266
267
268
269 if (cmd->unsolicited_data) {
270 cmd->unsolicited_data = 0;
271
272 offset = cmd->next_burst_len = cmd->write_data_done;
273
274 if ((conn->sess->sess_ops->FirstBurstLength - offset) >=
275 cmd->data_length) {
276 no_build_r2ts = 1;
277 length = (cmd->data_length - offset);
278 } else
279 length = (conn->sess->sess_ops->FirstBurstLength - offset);
280
281 spin_lock_bh(&cmd->r2t_lock);
282 if (iscsit_add_r2t_to_list(cmd, offset, length, 0, 0) < 0) {
283 spin_unlock_bh(&cmd->r2t_lock);
284 return -1;
285 }
286 cmd->outstanding_r2ts++;
287 spin_unlock_bh(&cmd->r2t_lock);
288
289 if (no_build_r2ts)
290 return 0;
291 }
292
293
294
295 return iscsit_build_r2ts_for_cmd(cmd, conn, 2);
296}
297
298static int iscsit_task_reassign_complete_read(
299 struct iscsi_cmd *cmd,
300 struct iscsi_tmr_req *tmr_req)
301{
302 struct iscsi_conn *conn = cmd->conn;
303 struct iscsi_datain_req *dr;
304 struct se_cmd *se_cmd = &cmd->se_cmd;
305
306
307
308
309 if (!tmr_req->exp_data_sn) {
310 cmd->cmd_flags &= ~ICF_GOT_DATACK_SNACK;
311 cmd->acked_data_sn = 0;
312 } else {
313 cmd->cmd_flags |= ICF_GOT_DATACK_SNACK;
314 cmd->acked_data_sn = (tmr_req->exp_data_sn - 1);
315 }
316
317 if (!atomic_read(&cmd->se_cmd.t_transport_sent)) {
318 pr_debug("READ ITT: 0x%08x: t_state: %d never sent to"
319 " transport\n", cmd->init_task_tag,
320 cmd->se_cmd.t_state);
321 transport_handle_cdb_direct(se_cmd);
322 return 0;
323 }
324
325 if (!atomic_read(&se_cmd->t_transport_complete)) {
326 pr_err("READ ITT: 0x%08x: t_state: %d, never returned"
327 " from transport\n", cmd->init_task_tag,
328 cmd->se_cmd.t_state);
329 return -1;
330 }
331
332 dr = iscsit_allocate_datain_req();
333 if (!dr)
334 return -1;
335
336
337
338
339 dr->data_sn = dr->begrun = tmr_req->exp_data_sn;
340 dr->runlength = 0;
341 dr->generate_recovery_values = 1;
342 dr->recovery = DATAIN_CONNECTION_RECOVERY;
343
344 iscsit_attach_datain_req(cmd, dr);
345
346 cmd->i_state = ISTATE_SEND_DATAIN;
347 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
348 return 0;
349}
350
351static int iscsit_task_reassign_complete_none(
352 struct iscsi_cmd *cmd,
353 struct iscsi_tmr_req *tmr_req)
354{
355 struct iscsi_conn *conn = cmd->conn;
356
357 cmd->i_state = ISTATE_SEND_STATUS;
358 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
359 return 0;
360}
361
362static int iscsit_task_reassign_complete_scsi_cmnd(
363 struct iscsi_tmr_req *tmr_req,
364 struct iscsi_conn *conn)
365{
366 struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
367 struct se_cmd *se_cmd = se_tmr->ref_cmd;
368 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
369 struct iscsi_conn_recovery *cr;
370
371 if (!cmd->cr) {
372 pr_err("struct iscsi_conn_recovery pointer for ITT: 0x%08x"
373 " is NULL!\n", cmd->init_task_tag);
374 return -1;
375 }
376 cr = cmd->cr;
377
378
379
380
381
382
383 cmd->stat_sn = cmd->exp_stat_sn = 0;
384
385 iscsit_task_reassign_remove_cmd(cmd, cr, conn->sess);
386
387 spin_lock_bh(&conn->cmd_lock);
388 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
389 spin_unlock_bh(&conn->cmd_lock);
390
391 if (se_cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
392 cmd->i_state = ISTATE_SEND_STATUS;
393 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
394 return 0;
395 }
396
397 switch (cmd->data_direction) {
398 case DMA_TO_DEVICE:
399 return iscsit_task_reassign_complete_write(cmd, tmr_req);
400 case DMA_FROM_DEVICE:
401 return iscsit_task_reassign_complete_read(cmd, tmr_req);
402 case DMA_NONE:
403 return iscsit_task_reassign_complete_none(cmd, tmr_req);
404 default:
405 pr_err("Unknown cmd->data_direction: 0x%02x\n",
406 cmd->data_direction);
407 return -1;
408 }
409
410 return 0;
411}
412
413static int iscsit_task_reassign_complete(
414 struct iscsi_tmr_req *tmr_req,
415 struct iscsi_conn *conn)
416{
417 struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
418 struct se_cmd *se_cmd;
419 struct iscsi_cmd *cmd;
420 int ret = 0;
421
422 if (!se_tmr->ref_cmd) {
423 pr_err("TMR Request is missing a RefCmd struct iscsi_cmd.\n");
424 return -1;
425 }
426 se_cmd = se_tmr->ref_cmd;
427 cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
428
429 cmd->conn = conn;
430
431 switch (cmd->iscsi_opcode) {
432 case ISCSI_OP_NOOP_OUT:
433 ret = iscsit_task_reassign_complete_nop_out(tmr_req, conn);
434 break;
435 case ISCSI_OP_SCSI_CMD:
436 ret = iscsit_task_reassign_complete_scsi_cmnd(tmr_req, conn);
437 break;
438 default:
439 pr_err("Illegal iSCSI Opcode 0x%02x during"
440 " command realligence\n", cmd->iscsi_opcode);
441 return -1;
442 }
443
444 if (ret != 0)
445 return ret;
446
447 pr_debug("Completed connection realligence for Opcode: 0x%02x,"
448 " ITT: 0x%08x to CID: %hu.\n", cmd->iscsi_opcode,
449 cmd->init_task_tag, conn->cid);
450
451 return 0;
452}
453
454
455
456
457
458
459extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
460{
461 struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
462 struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
463
464 if (tmr_req->task_reassign &&
465 (se_tmr->response == ISCSI_TMF_RSP_COMPLETE))
466 return iscsit_task_reassign_complete(tmr_req, conn);
467
468 return 0;
469}
470
471
472
473
474int iscsit_task_reassign_prepare_read(
475 struct iscsi_tmr_req *tmr_req,
476 struct iscsi_conn *conn)
477{
478 return 0;
479}
480
481static void iscsit_task_reassign_prepare_unsolicited_dataout(
482 struct iscsi_cmd *cmd,
483 struct iscsi_conn *conn)
484{
485 int i, j;
486 struct iscsi_pdu *pdu = NULL;
487 struct iscsi_seq *seq = NULL;
488
489 if (conn->sess->sess_ops->DataSequenceInOrder) {
490 cmd->data_sn = 0;
491
492 if (cmd->immediate_data)
493 cmd->r2t_offset += (cmd->first_burst_len -
494 cmd->seq_start_offset);
495
496 if (conn->sess->sess_ops->DataPDUInOrder) {
497 cmd->write_data_done -= (cmd->immediate_data) ?
498 (cmd->first_burst_len -
499 cmd->seq_start_offset) :
500 cmd->first_burst_len;
501 cmd->first_burst_len = 0;
502 return;
503 }
504
505 for (i = 0; i < cmd->pdu_count; i++) {
506 pdu = &cmd->pdu_list[i];
507
508 if (pdu->status != ISCSI_PDU_RECEIVED_OK)
509 continue;
510
511 if ((pdu->offset >= cmd->seq_start_offset) &&
512 ((pdu->offset + pdu->length) <=
513 cmd->seq_end_offset)) {
514 cmd->first_burst_len -= pdu->length;
515 cmd->write_data_done -= pdu->length;
516 pdu->status = ISCSI_PDU_NOT_RECEIVED;
517 }
518 }
519 } else {
520 for (i = 0; i < cmd->seq_count; i++) {
521 seq = &cmd->seq_list[i];
522
523 if (seq->type != SEQTYPE_UNSOLICITED)
524 continue;
525
526 cmd->write_data_done -=
527 (seq->offset - seq->orig_offset);
528 cmd->first_burst_len = 0;
529 seq->data_sn = 0;
530 seq->offset = seq->orig_offset;
531 seq->next_burst_len = 0;
532 seq->status = DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY;
533
534 if (conn->sess->sess_ops->DataPDUInOrder)
535 continue;
536
537 for (j = 0; j < seq->pdu_count; j++) {
538 pdu = &cmd->pdu_list[j+seq->pdu_start];
539
540 if (pdu->status != ISCSI_PDU_RECEIVED_OK)
541 continue;
542
543 pdu->status = ISCSI_PDU_NOT_RECEIVED;
544 }
545 }
546 }
547}
548
549int iscsit_task_reassign_prepare_write(
550 struct iscsi_tmr_req *tmr_req,
551 struct iscsi_conn *conn)
552{
553 struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
554 struct se_cmd *se_cmd = se_tmr->ref_cmd;
555 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
556 struct iscsi_pdu *pdu = NULL;
557 struct iscsi_r2t *r2t = NULL, *r2t_tmp;
558 int first_incomplete_r2t = 1, i = 0;
559
560
561
562
563
564 if (cmd->unsolicited_data)
565 iscsit_task_reassign_prepare_unsolicited_dataout(cmd, conn);
566
567
568
569
570
571
572 if (!tmr_req->exp_data_sn)
573 goto drop_unacknowledged_r2ts;
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588 spin_lock_bh(&cmd->r2t_lock);
589 if (list_empty(&cmd->cmd_r2t_list)) {
590 spin_unlock_bh(&cmd->r2t_lock);
591 return -1;
592 }
593
594 list_for_each_entry(r2t, &cmd->cmd_r2t_list, r2t_list) {
595
596 if (r2t->r2t_sn >= tmr_req->exp_data_sn)
597 continue;
598
599
600
601
602 if (r2t->seq_complete)
603 continue;
604
605 if (r2t->recovery_r2t)
606 continue;
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641 if (conn->sess->sess_ops->DataSequenceInOrder) {
642 if (!first_incomplete_r2t) {
643 cmd->r2t_offset -= r2t->xfer_len;
644 goto next;
645 }
646
647 if (conn->sess->sess_ops->DataPDUInOrder) {
648 cmd->data_sn = 0;
649 cmd->r2t_offset -= (r2t->xfer_len -
650 cmd->next_burst_len);
651 first_incomplete_r2t = 0;
652 goto next;
653 }
654
655 cmd->data_sn = 0;
656 cmd->r2t_offset -= r2t->xfer_len;
657
658 for (i = 0; i < cmd->pdu_count; i++) {
659 pdu = &cmd->pdu_list[i];
660
661 if (pdu->status != ISCSI_PDU_RECEIVED_OK)
662 continue;
663
664 if ((pdu->offset >= r2t->offset) &&
665 (pdu->offset < (r2t->offset +
666 r2t->xfer_len))) {
667 cmd->next_burst_len -= pdu->length;
668 cmd->write_data_done -= pdu->length;
669 pdu->status = ISCSI_PDU_NOT_RECEIVED;
670 }
671 }
672
673 first_incomplete_r2t = 0;
674 } else {
675 struct iscsi_seq *seq;
676
677 seq = iscsit_get_seq_holder(cmd, r2t->offset,
678 r2t->xfer_len);
679 if (!seq) {
680 spin_unlock_bh(&cmd->r2t_lock);
681 return -1;
682 }
683
684 cmd->write_data_done -=
685 (seq->offset - seq->orig_offset);
686 seq->data_sn = 0;
687 seq->offset = seq->orig_offset;
688 seq->next_burst_len = 0;
689 seq->status = DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY;
690
691 cmd->seq_send_order--;
692
693 if (conn->sess->sess_ops->DataPDUInOrder)
694 goto next;
695
696 for (i = 0; i < seq->pdu_count; i++) {
697 pdu = &cmd->pdu_list[i+seq->pdu_start];
698
699 if (pdu->status != ISCSI_PDU_RECEIVED_OK)
700 continue;
701
702 pdu->status = ISCSI_PDU_NOT_RECEIVED;
703 }
704 }
705
706next:
707 cmd->outstanding_r2ts--;
708 }
709 spin_unlock_bh(&cmd->r2t_lock);
710
711
712
713
714
715
716
717
718
719
720
721drop_unacknowledged_r2ts:
722
723 cmd->cmd_flags &= ~ICF_SENT_LAST_R2T;
724 cmd->r2t_sn = tmr_req->exp_data_sn;
725
726 spin_lock_bh(&cmd->r2t_lock);
727 list_for_each_entry_safe(r2t, r2t_tmp, &cmd->cmd_r2t_list, r2t_list) {
728
729
730
731
732 if (r2t->r2t_sn < tmr_req->exp_data_sn)
733 continue;
734
735 if (r2t->seq_complete) {
736 pr_err("Initiator is requesting R2Ts from"
737 " R2TSN: 0x%08x, but R2TSN: 0x%08x, Offset: %u,"
738 " Length: %u is already complete."
739 " BAD INITIATOR ERL=2 IMPLEMENTATION!\n",
740 tmr_req->exp_data_sn, r2t->r2t_sn,
741 r2t->offset, r2t->xfer_len);
742 spin_unlock_bh(&cmd->r2t_lock);
743 return -1;
744 }
745
746 if (r2t->recovery_r2t) {
747 iscsit_free_r2t(r2t, cmd);
748 continue;
749 }
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767 if (conn->sess->sess_ops->DataSequenceInOrder)
768 cmd->r2t_offset -= r2t->xfer_len;
769 else
770 cmd->seq_send_order--;
771
772 cmd->outstanding_r2ts--;
773 iscsit_free_r2t(r2t, cmd);
774 }
775 spin_unlock_bh(&cmd->r2t_lock);
776
777 return 0;
778}
779
780
781
782
783
784int iscsit_check_task_reassign_expdatasn(
785 struct iscsi_tmr_req *tmr_req,
786 struct iscsi_conn *conn)
787{
788 struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
789 struct se_cmd *se_cmd = se_tmr->ref_cmd;
790 struct iscsi_cmd *ref_cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
791
792 if (ref_cmd->iscsi_opcode != ISCSI_OP_SCSI_CMD)
793 return 0;
794
795 if (se_cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION)
796 return 0;
797
798 if (ref_cmd->data_direction == DMA_NONE)
799 return 0;
800
801
802
803
804
805
806
807
808 if (ref_cmd->data_direction == DMA_FROM_DEVICE) {
809 if (tmr_req->exp_data_sn > ref_cmd->data_sn) {
810 pr_err("Received ExpDataSN: 0x%08x for READ"
811 " in TMR TASK_REASSIGN greater than command's"
812 " DataSN: 0x%08x.\n", tmr_req->exp_data_sn,
813 ref_cmd->data_sn);
814 return -1;
815 }
816 if ((ref_cmd->cmd_flags & ICF_GOT_DATACK_SNACK) &&
817 (tmr_req->exp_data_sn <= ref_cmd->acked_data_sn)) {
818 pr_err("Received ExpDataSN: 0x%08x for READ"
819 " in TMR TASK_REASSIGN for previously"
820 " acknowledged DataIN: 0x%08x,"
821 " protocol error\n", tmr_req->exp_data_sn,
822 ref_cmd->acked_data_sn);
823 return -1;
824 }
825 return iscsit_task_reassign_prepare_read(tmr_req, conn);
826 }
827
828
829
830
831
832
833
834 if (ref_cmd->data_direction == DMA_TO_DEVICE) {
835 if (tmr_req->exp_data_sn > ref_cmd->r2t_sn) {
836 pr_err("Received ExpDataSN: 0x%08x for WRITE"
837 " in TMR TASK_REASSIGN greater than command's"
838 " R2TSN: 0x%08x.\n", tmr_req->exp_data_sn,
839 ref_cmd->r2t_sn);
840 return -1;
841 }
842 return iscsit_task_reassign_prepare_write(tmr_req, conn);
843 }
844
845 pr_err("Unknown iSCSI data_direction: 0x%02x\n",
846 ref_cmd->data_direction);
847
848 return -1;
849}
850