net: qmi_wwan: add Olivetti Olicard 500
[linux/fpc-iii.git] / drivers / target / iscsi / iscsi_target_erl0.c
blob0d1e6ee3e99246d5b613641237df8ea01a1dcfd2
1 /******************************************************************************
2 * This file contains error recovery level zero functions used by
3 * the iSCSI Target driver.
5 * (c) Copyright 2007-2013 Datera, Inc.
7 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 ******************************************************************************/
20 #include <scsi/iscsi_proto.h>
21 #include <target/target_core_base.h>
22 #include <target/target_core_fabric.h>
24 #include "iscsi_target_core.h"
25 #include "iscsi_target_seq_pdu_list.h"
26 #include "iscsi_target_tq.h"
27 #include "iscsi_target_erl0.h"
28 #include "iscsi_target_erl1.h"
29 #include "iscsi_target_erl2.h"
30 #include "iscsi_target_util.h"
31 #include "iscsi_target.h"
34 * Used to set values in struct iscsi_cmd that iscsit_dataout_check_sequence()
35 * checks against to determine a PDU's Offset+Length is within the current
36 * DataOUT Sequence. Used for DataSequenceInOrder=Yes only.
38 void iscsit_set_dataout_sequence_values(
39 struct iscsi_cmd *cmd)
41 struct iscsi_conn *conn = cmd->conn;
43 * Still set seq_start_offset and seq_end_offset for Unsolicited
44 * DataOUT, even if DataSequenceInOrder=No.
46 if (cmd->unsolicited_data) {
47 cmd->seq_start_offset = cmd->write_data_done;
48 cmd->seq_end_offset = (cmd->write_data_done +
49 ((cmd->se_cmd.data_length >
50 conn->sess->sess_ops->FirstBurstLength) ?
51 conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length));
52 return;
55 if (!conn->sess->sess_ops->DataSequenceInOrder)
56 return;
58 if (!cmd->seq_start_offset && !cmd->seq_end_offset) {
59 cmd->seq_start_offset = cmd->write_data_done;
60 cmd->seq_end_offset = (cmd->se_cmd.data_length >
61 conn->sess->sess_ops->MaxBurstLength) ?
62 (cmd->write_data_done +
63 conn->sess->sess_ops->MaxBurstLength) : cmd->se_cmd.data_length;
64 } else {
65 cmd->seq_start_offset = cmd->seq_end_offset;
66 cmd->seq_end_offset = ((cmd->seq_end_offset +
67 conn->sess->sess_ops->MaxBurstLength) >=
68 cmd->se_cmd.data_length) ? cmd->se_cmd.data_length :
69 (cmd->seq_end_offset +
70 conn->sess->sess_ops->MaxBurstLength);
74 static int iscsit_dataout_within_command_recovery_check(
75 struct iscsi_cmd *cmd,
76 unsigned char *buf)
78 struct iscsi_conn *conn = cmd->conn;
79 struct iscsi_data *hdr = (struct iscsi_data *) buf;
80 u32 payload_length = ntoh24(hdr->dlength);
83 * We do the within-command recovery checks here as it is
84 * the first function called in iscsi_check_pre_dataout().
85 * Basically, if we are in within-command recovery and
86 * the PDU does not contain the offset the sequence needs,
87 * dump the payload.
89 * This only applies to DataPDUInOrder=Yes, for
90 * DataPDUInOrder=No we only re-request the failed PDU
91 * and check that all PDUs in a sequence are received
92 * upon end of sequence.
94 if (conn->sess->sess_ops->DataSequenceInOrder) {
95 if ((cmd->cmd_flags & ICF_WITHIN_COMMAND_RECOVERY) &&
96 cmd->write_data_done != be32_to_cpu(hdr->offset))
97 goto dump;
99 cmd->cmd_flags &= ~ICF_WITHIN_COMMAND_RECOVERY;
100 } else {
101 struct iscsi_seq *seq;
103 seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
104 payload_length);
105 if (!seq)
106 return DATAOUT_CANNOT_RECOVER;
108 * Set the struct iscsi_seq pointer to reuse later.
110 cmd->seq_ptr = seq;
112 if (conn->sess->sess_ops->DataPDUInOrder) {
113 if (seq->status ==
114 DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
115 (seq->offset != be32_to_cpu(hdr->offset) ||
116 seq->data_sn != be32_to_cpu(hdr->datasn)))
117 goto dump;
118 } else {
119 if (seq->status ==
120 DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
121 seq->data_sn != be32_to_cpu(hdr->datasn))
122 goto dump;
125 if (seq->status == DATAOUT_SEQUENCE_COMPLETE)
126 goto dump;
128 if (seq->status != DATAOUT_SEQUENCE_COMPLETE)
129 seq->status = 0;
132 return DATAOUT_NORMAL;
134 dump:
135 pr_err("Dumping DataOUT PDU Offset: %u Length: %d DataSN:"
136 " 0x%08x\n", hdr->offset, payload_length, hdr->datasn);
137 return iscsit_dump_data_payload(conn, payload_length, 1);
140 static int iscsit_dataout_check_unsolicited_sequence(
141 struct iscsi_cmd *cmd,
142 unsigned char *buf)
144 u32 first_burst_len;
145 struct iscsi_conn *conn = cmd->conn;
146 struct iscsi_data *hdr = (struct iscsi_data *) buf;
147 u32 payload_length = ntoh24(hdr->dlength);
150 if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
151 ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
152 pr_err("Command ITT: 0x%08x with Offset: %u,"
153 " Length: %u outside of Unsolicited Sequence %u:%u while"
154 " DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
155 be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
156 cmd->seq_end_offset);
157 return DATAOUT_CANNOT_RECOVER;
160 first_burst_len = (cmd->first_burst_len + payload_length);
162 if (first_burst_len > conn->sess->sess_ops->FirstBurstLength) {
163 pr_err("Total %u bytes exceeds FirstBurstLength: %u"
164 " for this Unsolicited DataOut Burst.\n",
165 first_burst_len, conn->sess->sess_ops->FirstBurstLength);
166 transport_send_check_condition_and_sense(&cmd->se_cmd,
167 TCM_INCORRECT_AMOUNT_OF_DATA, 0);
168 return DATAOUT_CANNOT_RECOVER;
172 * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
173 * checks for the current Unsolicited DataOUT Sequence.
175 if (hdr->flags & ISCSI_FLAG_CMD_FINAL) {
177 * Ignore ISCSI_FLAG_CMD_FINAL checks while DataPDUInOrder=No, end of
178 * sequence checks are handled in
179 * iscsit_dataout_datapduinorder_no_fbit().
181 if (!conn->sess->sess_ops->DataPDUInOrder)
182 goto out;
184 if ((first_burst_len != cmd->se_cmd.data_length) &&
185 (first_burst_len != conn->sess->sess_ops->FirstBurstLength)) {
186 pr_err("Unsolicited non-immediate data"
187 " received %u does not equal FirstBurstLength: %u, and"
188 " does not equal ExpXferLen %u.\n", first_burst_len,
189 conn->sess->sess_ops->FirstBurstLength,
190 cmd->se_cmd.data_length);
191 transport_send_check_condition_and_sense(&cmd->se_cmd,
192 TCM_INCORRECT_AMOUNT_OF_DATA, 0);
193 return DATAOUT_CANNOT_RECOVER;
195 } else {
196 if (first_burst_len == conn->sess->sess_ops->FirstBurstLength) {
197 pr_err("Command ITT: 0x%08x reached"
198 " FirstBurstLength: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
199 " error.\n", cmd->init_task_tag,
200 conn->sess->sess_ops->FirstBurstLength);
201 return DATAOUT_CANNOT_RECOVER;
203 if (first_burst_len == cmd->se_cmd.data_length) {
204 pr_err("Command ITT: 0x%08x reached"
205 " ExpXferLen: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
206 " error.\n", cmd->init_task_tag, cmd->se_cmd.data_length);
207 return DATAOUT_CANNOT_RECOVER;
211 out:
212 return DATAOUT_NORMAL;
215 static int iscsit_dataout_check_sequence(
216 struct iscsi_cmd *cmd,
217 unsigned char *buf)
219 u32 next_burst_len;
220 struct iscsi_conn *conn = cmd->conn;
221 struct iscsi_seq *seq = NULL;
222 struct iscsi_data *hdr = (struct iscsi_data *) buf;
223 u32 payload_length = ntoh24(hdr->dlength);
226 * For DataSequenceInOrder=Yes: Check that the offset and offset+length
227 * is within range as defined by iscsi_set_dataout_sequence_values().
229 * For DataSequenceInOrder=No: Check that an struct iscsi_seq exists for
230 * offset+length tuple.
232 if (conn->sess->sess_ops->DataSequenceInOrder) {
234 * Due to possibility of recovery DataOUT sent by the initiator
235 * fullfilling an Recovery R2T, it's best to just dump the
236 * payload here, instead of erroring out.
238 if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
239 ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
240 pr_err("Command ITT: 0x%08x with Offset: %u,"
241 " Length: %u outside of Sequence %u:%u while"
242 " DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
243 be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
244 cmd->seq_end_offset);
246 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
247 return DATAOUT_CANNOT_RECOVER;
248 return DATAOUT_WITHIN_COMMAND_RECOVERY;
251 next_burst_len = (cmd->next_burst_len + payload_length);
252 } else {
253 seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
254 payload_length);
255 if (!seq)
256 return DATAOUT_CANNOT_RECOVER;
258 * Set the struct iscsi_seq pointer to reuse later.
260 cmd->seq_ptr = seq;
262 if (seq->status == DATAOUT_SEQUENCE_COMPLETE) {
263 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
264 return DATAOUT_CANNOT_RECOVER;
265 return DATAOUT_WITHIN_COMMAND_RECOVERY;
268 next_burst_len = (seq->next_burst_len + payload_length);
271 if (next_burst_len > conn->sess->sess_ops->MaxBurstLength) {
272 pr_err("Command ITT: 0x%08x, NextBurstLength: %u and"
273 " Length: %u exceeds MaxBurstLength: %u. protocol"
274 " error.\n", cmd->init_task_tag,
275 (next_burst_len - payload_length),
276 payload_length, conn->sess->sess_ops->MaxBurstLength);
277 return DATAOUT_CANNOT_RECOVER;
281 * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
282 * checks for the current DataOUT Sequence.
284 if (hdr->flags & ISCSI_FLAG_CMD_FINAL) {
286 * Ignore ISCSI_FLAG_CMD_FINAL checks while DataPDUInOrder=No, end of
287 * sequence checks are handled in
288 * iscsit_dataout_datapduinorder_no_fbit().
290 if (!conn->sess->sess_ops->DataPDUInOrder)
291 goto out;
293 if (conn->sess->sess_ops->DataSequenceInOrder) {
294 if ((next_burst_len <
295 conn->sess->sess_ops->MaxBurstLength) &&
296 ((cmd->write_data_done + payload_length) <
297 cmd->se_cmd.data_length)) {
298 pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
299 " before end of DataOUT sequence, protocol"
300 " error.\n", cmd->init_task_tag);
301 return DATAOUT_CANNOT_RECOVER;
303 } else {
304 if (next_burst_len < seq->xfer_len) {
305 pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
306 " before end of DataOUT sequence, protocol"
307 " error.\n", cmd->init_task_tag);
308 return DATAOUT_CANNOT_RECOVER;
311 } else {
312 if (conn->sess->sess_ops->DataSequenceInOrder) {
313 if (next_burst_len ==
314 conn->sess->sess_ops->MaxBurstLength) {
315 pr_err("Command ITT: 0x%08x reached"
316 " MaxBurstLength: %u, but ISCSI_FLAG_CMD_FINAL is"
317 " not set, protocol error.", cmd->init_task_tag,
318 conn->sess->sess_ops->MaxBurstLength);
319 return DATAOUT_CANNOT_RECOVER;
321 if ((cmd->write_data_done + payload_length) ==
322 cmd->se_cmd.data_length) {
323 pr_err("Command ITT: 0x%08x reached"
324 " last DataOUT PDU in sequence but ISCSI_FLAG_"
325 "CMD_FINAL is not set, protocol error.\n",
326 cmd->init_task_tag);
327 return DATAOUT_CANNOT_RECOVER;
329 } else {
330 if (next_burst_len == seq->xfer_len) {
331 pr_err("Command ITT: 0x%08x reached"
332 " last DataOUT PDU in sequence but ISCSI_FLAG_"
333 "CMD_FINAL is not set, protocol error.\n",
334 cmd->init_task_tag);
335 return DATAOUT_CANNOT_RECOVER;
340 out:
341 return DATAOUT_NORMAL;
344 static int iscsit_dataout_check_datasn(
345 struct iscsi_cmd *cmd,
346 unsigned char *buf)
348 int dump = 0, recovery = 0;
349 u32 data_sn = 0;
350 struct iscsi_conn *conn = cmd->conn;
351 struct iscsi_data *hdr = (struct iscsi_data *) buf;
352 u32 payload_length = ntoh24(hdr->dlength);
355 * Considering the target has no method of re-requesting DataOUT
356 * by DataSN, if we receieve a greater DataSN than expected we
357 * assume the functions for DataPDUInOrder=[Yes,No] below will
358 * handle it.
360 * If the DataSN is less than expected, dump the payload.
362 if (conn->sess->sess_ops->DataSequenceInOrder)
363 data_sn = cmd->data_sn;
364 else {
365 struct iscsi_seq *seq = cmd->seq_ptr;
366 data_sn = seq->data_sn;
369 if (be32_to_cpu(hdr->datasn) > data_sn) {
370 pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
371 " higher than expected 0x%08x.\n", cmd->init_task_tag,
372 be32_to_cpu(hdr->datasn), data_sn);
373 recovery = 1;
374 goto recover;
375 } else if (be32_to_cpu(hdr->datasn) < data_sn) {
376 pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
377 " lower than expected 0x%08x, discarding payload.\n",
378 cmd->init_task_tag, be32_to_cpu(hdr->datasn), data_sn);
379 dump = 1;
380 goto dump;
383 return DATAOUT_NORMAL;
385 recover:
386 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
387 pr_err("Unable to perform within-command recovery"
388 " while ERL=0.\n");
389 return DATAOUT_CANNOT_RECOVER;
391 dump:
392 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
393 return DATAOUT_CANNOT_RECOVER;
395 return (recovery || dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY :
396 DATAOUT_NORMAL;
399 static int iscsit_dataout_pre_datapduinorder_yes(
400 struct iscsi_cmd *cmd,
401 unsigned char *buf)
403 int dump = 0, recovery = 0;
404 struct iscsi_conn *conn = cmd->conn;
405 struct iscsi_data *hdr = (struct iscsi_data *) buf;
406 u32 payload_length = ntoh24(hdr->dlength);
409 * For DataSequenceInOrder=Yes: If the offset is greater than the global
410 * DataPDUInOrder=Yes offset counter in struct iscsi_cmd a protcol error has
411 * occurred and fail the connection.
413 * For DataSequenceInOrder=No: If the offset is greater than the per
414 * sequence DataPDUInOrder=Yes offset counter in struct iscsi_seq a protocol
415 * error has occurred and fail the connection.
417 if (conn->sess->sess_ops->DataSequenceInOrder) {
418 if (be32_to_cpu(hdr->offset) != cmd->write_data_done) {
419 pr_err("Command ITT: 0x%08x, received offset"
420 " %u different than expected %u.\n", cmd->init_task_tag,
421 be32_to_cpu(hdr->offset), cmd->write_data_done);
422 recovery = 1;
423 goto recover;
425 } else {
426 struct iscsi_seq *seq = cmd->seq_ptr;
428 if (be32_to_cpu(hdr->offset) > seq->offset) {
429 pr_err("Command ITT: 0x%08x, received offset"
430 " %u greater than expected %u.\n", cmd->init_task_tag,
431 be32_to_cpu(hdr->offset), seq->offset);
432 recovery = 1;
433 goto recover;
434 } else if (be32_to_cpu(hdr->offset) < seq->offset) {
435 pr_err("Command ITT: 0x%08x, received offset"
436 " %u less than expected %u, discarding payload.\n",
437 cmd->init_task_tag, be32_to_cpu(hdr->offset),
438 seq->offset);
439 dump = 1;
440 goto dump;
444 return DATAOUT_NORMAL;
446 recover:
447 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
448 pr_err("Unable to perform within-command recovery"
449 " while ERL=0.\n");
450 return DATAOUT_CANNOT_RECOVER;
452 dump:
453 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
454 return DATAOUT_CANNOT_RECOVER;
456 return (recovery) ? iscsit_recover_dataout_sequence(cmd,
457 be32_to_cpu(hdr->offset), payload_length) :
458 (dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL;
461 static int iscsit_dataout_pre_datapduinorder_no(
462 struct iscsi_cmd *cmd,
463 unsigned char *buf)
465 struct iscsi_pdu *pdu;
466 struct iscsi_data *hdr = (struct iscsi_data *) buf;
467 u32 payload_length = ntoh24(hdr->dlength);
469 pdu = iscsit_get_pdu_holder(cmd, be32_to_cpu(hdr->offset),
470 payload_length);
471 if (!pdu)
472 return DATAOUT_CANNOT_RECOVER;
474 cmd->pdu_ptr = pdu;
476 switch (pdu->status) {
477 case ISCSI_PDU_NOT_RECEIVED:
478 case ISCSI_PDU_CRC_FAILED:
479 case ISCSI_PDU_TIMED_OUT:
480 break;
481 case ISCSI_PDU_RECEIVED_OK:
482 pr_err("Command ITT: 0x%08x received already gotten"
483 " Offset: %u, Length: %u\n", cmd->init_task_tag,
484 be32_to_cpu(hdr->offset), payload_length);
485 return iscsit_dump_data_payload(cmd->conn, payload_length, 1);
486 default:
487 return DATAOUT_CANNOT_RECOVER;
490 return DATAOUT_NORMAL;
493 static int iscsit_dataout_update_r2t(struct iscsi_cmd *cmd, u32 offset, u32 length)
495 struct iscsi_r2t *r2t;
497 if (cmd->unsolicited_data)
498 return 0;
500 r2t = iscsit_get_r2t_for_eos(cmd, offset, length);
501 if (!r2t)
502 return -1;
504 spin_lock_bh(&cmd->r2t_lock);
505 r2t->seq_complete = 1;
506 cmd->outstanding_r2ts--;
507 spin_unlock_bh(&cmd->r2t_lock);
509 return 0;
512 static int iscsit_dataout_update_datapduinorder_no(
513 struct iscsi_cmd *cmd,
514 u32 data_sn,
515 int f_bit)
517 int ret = 0;
518 struct iscsi_pdu *pdu = cmd->pdu_ptr;
520 pdu->data_sn = data_sn;
522 switch (pdu->status) {
523 case ISCSI_PDU_NOT_RECEIVED:
524 pdu->status = ISCSI_PDU_RECEIVED_OK;
525 break;
526 case ISCSI_PDU_CRC_FAILED:
527 pdu->status = ISCSI_PDU_RECEIVED_OK;
528 break;
529 case ISCSI_PDU_TIMED_OUT:
530 pdu->status = ISCSI_PDU_RECEIVED_OK;
531 break;
532 default:
533 return DATAOUT_CANNOT_RECOVER;
536 if (f_bit) {
537 ret = iscsit_dataout_datapduinorder_no_fbit(cmd, pdu);
538 if (ret == DATAOUT_CANNOT_RECOVER)
539 return ret;
542 return DATAOUT_NORMAL;
545 static int iscsit_dataout_post_crc_passed(
546 struct iscsi_cmd *cmd,
547 unsigned char *buf)
549 int ret, send_r2t = 0;
550 struct iscsi_conn *conn = cmd->conn;
551 struct iscsi_seq *seq = NULL;
552 struct iscsi_data *hdr = (struct iscsi_data *) buf;
553 u32 payload_length = ntoh24(hdr->dlength);
555 if (cmd->unsolicited_data) {
556 if ((cmd->first_burst_len + payload_length) ==
557 conn->sess->sess_ops->FirstBurstLength) {
558 if (iscsit_dataout_update_r2t(cmd, be32_to_cpu(hdr->offset),
559 payload_length) < 0)
560 return DATAOUT_CANNOT_RECOVER;
561 send_r2t = 1;
564 if (!conn->sess->sess_ops->DataPDUInOrder) {
565 ret = iscsit_dataout_update_datapduinorder_no(cmd,
566 be32_to_cpu(hdr->datasn),
567 (hdr->flags & ISCSI_FLAG_CMD_FINAL));
568 if (ret == DATAOUT_CANNOT_RECOVER)
569 return ret;
572 cmd->first_burst_len += payload_length;
574 if (conn->sess->sess_ops->DataSequenceInOrder)
575 cmd->data_sn++;
576 else {
577 seq = cmd->seq_ptr;
578 seq->data_sn++;
579 seq->offset += payload_length;
582 if (send_r2t) {
583 if (seq)
584 seq->status = DATAOUT_SEQUENCE_COMPLETE;
585 cmd->first_burst_len = 0;
586 cmd->unsolicited_data = 0;
588 } else {
589 if (conn->sess->sess_ops->DataSequenceInOrder) {
590 if ((cmd->next_burst_len + payload_length) ==
591 conn->sess->sess_ops->MaxBurstLength) {
592 if (iscsit_dataout_update_r2t(cmd,
593 be32_to_cpu(hdr->offset),
594 payload_length) < 0)
595 return DATAOUT_CANNOT_RECOVER;
596 send_r2t = 1;
599 if (!conn->sess->sess_ops->DataPDUInOrder) {
600 ret = iscsit_dataout_update_datapduinorder_no(
601 cmd, be32_to_cpu(hdr->datasn),
602 (hdr->flags & ISCSI_FLAG_CMD_FINAL));
603 if (ret == DATAOUT_CANNOT_RECOVER)
604 return ret;
607 cmd->next_burst_len += payload_length;
608 cmd->data_sn++;
610 if (send_r2t)
611 cmd->next_burst_len = 0;
612 } else {
613 seq = cmd->seq_ptr;
615 if ((seq->next_burst_len + payload_length) ==
616 seq->xfer_len) {
617 if (iscsit_dataout_update_r2t(cmd,
618 be32_to_cpu(hdr->offset),
619 payload_length) < 0)
620 return DATAOUT_CANNOT_RECOVER;
621 send_r2t = 1;
624 if (!conn->sess->sess_ops->DataPDUInOrder) {
625 ret = iscsit_dataout_update_datapduinorder_no(
626 cmd, be32_to_cpu(hdr->datasn),
627 (hdr->flags & ISCSI_FLAG_CMD_FINAL));
628 if (ret == DATAOUT_CANNOT_RECOVER)
629 return ret;
632 seq->data_sn++;
633 seq->offset += payload_length;
634 seq->next_burst_len += payload_length;
636 if (send_r2t) {
637 seq->next_burst_len = 0;
638 seq->status = DATAOUT_SEQUENCE_COMPLETE;
643 if (send_r2t && conn->sess->sess_ops->DataSequenceInOrder)
644 cmd->data_sn = 0;
646 cmd->write_data_done += payload_length;
648 if (cmd->write_data_done == cmd->se_cmd.data_length)
649 return DATAOUT_SEND_TO_TRANSPORT;
650 else if (send_r2t)
651 return DATAOUT_SEND_R2T;
652 else
653 return DATAOUT_NORMAL;
656 static int iscsit_dataout_post_crc_failed(
657 struct iscsi_cmd *cmd,
658 unsigned char *buf)
660 struct iscsi_conn *conn = cmd->conn;
661 struct iscsi_pdu *pdu;
662 struct iscsi_data *hdr = (struct iscsi_data *) buf;
663 u32 payload_length = ntoh24(hdr->dlength);
665 if (conn->sess->sess_ops->DataPDUInOrder)
666 goto recover;
668 * The rest of this function is only called when DataPDUInOrder=No.
670 pdu = cmd->pdu_ptr;
672 switch (pdu->status) {
673 case ISCSI_PDU_NOT_RECEIVED:
674 pdu->status = ISCSI_PDU_CRC_FAILED;
675 break;
676 case ISCSI_PDU_CRC_FAILED:
677 break;
678 case ISCSI_PDU_TIMED_OUT:
679 pdu->status = ISCSI_PDU_CRC_FAILED;
680 break;
681 default:
682 return DATAOUT_CANNOT_RECOVER;
685 recover:
686 return iscsit_recover_dataout_sequence(cmd, be32_to_cpu(hdr->offset),
687 payload_length);
691 * Called from iscsit_handle_data_out() before DataOUT Payload is received
692 * and CRC computed.
694 int iscsit_check_pre_dataout(
695 struct iscsi_cmd *cmd,
696 unsigned char *buf)
698 int ret;
699 struct iscsi_conn *conn = cmd->conn;
701 ret = iscsit_dataout_within_command_recovery_check(cmd, buf);
702 if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
703 (ret == DATAOUT_CANNOT_RECOVER))
704 return ret;
706 ret = iscsit_dataout_check_datasn(cmd, buf);
707 if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
708 (ret == DATAOUT_CANNOT_RECOVER))
709 return ret;
711 if (cmd->unsolicited_data) {
712 ret = iscsit_dataout_check_unsolicited_sequence(cmd, buf);
713 if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
714 (ret == DATAOUT_CANNOT_RECOVER))
715 return ret;
716 } else {
717 ret = iscsit_dataout_check_sequence(cmd, buf);
718 if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
719 (ret == DATAOUT_CANNOT_RECOVER))
720 return ret;
723 return (conn->sess->sess_ops->DataPDUInOrder) ?
724 iscsit_dataout_pre_datapduinorder_yes(cmd, buf) :
725 iscsit_dataout_pre_datapduinorder_no(cmd, buf);
729 * Called from iscsit_handle_data_out() after DataOUT Payload is received
730 * and CRC computed.
732 int iscsit_check_post_dataout(
733 struct iscsi_cmd *cmd,
734 unsigned char *buf,
735 u8 data_crc_failed)
737 struct iscsi_conn *conn = cmd->conn;
739 cmd->dataout_timeout_retries = 0;
741 if (!data_crc_failed)
742 return iscsit_dataout_post_crc_passed(cmd, buf);
743 else {
744 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
745 pr_err("Unable to recover from DataOUT CRC"
746 " failure while ERL=0, closing session.\n");
747 iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR,
748 buf);
749 return DATAOUT_CANNOT_RECOVER;
752 iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, buf);
753 return iscsit_dataout_post_crc_failed(cmd, buf);
757 static void iscsit_handle_time2retain_timeout(unsigned long data)
759 struct iscsi_session *sess = (struct iscsi_session *) data;
760 struct iscsi_portal_group *tpg = sess->tpg;
761 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
763 spin_lock_bh(&se_tpg->session_lock);
764 if (sess->time2retain_timer_flags & ISCSI_TF_STOP) {
765 spin_unlock_bh(&se_tpg->session_lock);
766 return;
768 if (atomic_read(&sess->session_reinstatement)) {
769 pr_err("Exiting Time2Retain handler because"
770 " session_reinstatement=1\n");
771 spin_unlock_bh(&se_tpg->session_lock);
772 return;
774 sess->time2retain_timer_flags |= ISCSI_TF_EXPIRED;
776 pr_err("Time2Retain timer expired for SID: %u, cleaning up"
777 " iSCSI session.\n", sess->sid);
779 struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
781 if (tiqn) {
782 spin_lock(&tiqn->sess_err_stats.lock);
783 strcpy(tiqn->sess_err_stats.last_sess_fail_rem_name,
784 (void *)sess->sess_ops->InitiatorName);
785 tiqn->sess_err_stats.last_sess_failure_type =
786 ISCSI_SESS_ERR_CXN_TIMEOUT;
787 tiqn->sess_err_stats.cxn_timeout_errors++;
788 atomic_long_inc(&sess->conn_timeout_errors);
789 spin_unlock(&tiqn->sess_err_stats.lock);
793 spin_unlock_bh(&se_tpg->session_lock);
794 target_put_session(sess->se_sess);
797 void iscsit_start_time2retain_handler(struct iscsi_session *sess)
799 int tpg_active;
801 * Only start Time2Retain timer when the associated TPG is still in
802 * an ACTIVE (eg: not disabled or shutdown) state.
804 spin_lock(&sess->tpg->tpg_state_lock);
805 tpg_active = (sess->tpg->tpg_state == TPG_STATE_ACTIVE);
806 spin_unlock(&sess->tpg->tpg_state_lock);
808 if (!tpg_active)
809 return;
811 if (sess->time2retain_timer_flags & ISCSI_TF_RUNNING)
812 return;
814 pr_debug("Starting Time2Retain timer for %u seconds on"
815 " SID: %u\n", sess->sess_ops->DefaultTime2Retain, sess->sid);
817 init_timer(&sess->time2retain_timer);
818 sess->time2retain_timer.expires =
819 (get_jiffies_64() + sess->sess_ops->DefaultTime2Retain * HZ);
820 sess->time2retain_timer.data = (unsigned long)sess;
821 sess->time2retain_timer.function = iscsit_handle_time2retain_timeout;
822 sess->time2retain_timer_flags &= ~ISCSI_TF_STOP;
823 sess->time2retain_timer_flags |= ISCSI_TF_RUNNING;
824 add_timer(&sess->time2retain_timer);
828 * Called with spin_lock_bh(&struct se_portal_group->session_lock) held
830 int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
832 struct iscsi_portal_group *tpg = sess->tpg;
833 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
835 if (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)
836 return -1;
838 if (!(sess->time2retain_timer_flags & ISCSI_TF_RUNNING))
839 return 0;
841 sess->time2retain_timer_flags |= ISCSI_TF_STOP;
842 spin_unlock(&se_tpg->session_lock);
844 del_timer_sync(&sess->time2retain_timer);
846 spin_lock(&se_tpg->session_lock);
847 sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING;
848 pr_debug("Stopped Time2Retain Timer for SID: %u\n",
849 sess->sid);
850 return 0;
853 void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *conn)
855 spin_lock_bh(&conn->state_lock);
856 if (atomic_read(&conn->connection_exit)) {
857 spin_unlock_bh(&conn->state_lock);
858 goto sleep;
861 if (atomic_read(&conn->transport_failed)) {
862 spin_unlock_bh(&conn->state_lock);
863 goto sleep;
865 spin_unlock_bh(&conn->state_lock);
867 iscsi_thread_set_force_reinstatement(conn);
869 sleep:
870 wait_for_completion(&conn->conn_wait_rcfr_comp);
871 complete(&conn->conn_post_wait_comp);
874 void iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep)
876 spin_lock_bh(&conn->state_lock);
877 if (atomic_read(&conn->connection_exit)) {
878 spin_unlock_bh(&conn->state_lock);
879 return;
882 if (atomic_read(&conn->transport_failed)) {
883 spin_unlock_bh(&conn->state_lock);
884 return;
887 if (atomic_read(&conn->connection_reinstatement)) {
888 spin_unlock_bh(&conn->state_lock);
889 return;
892 if (iscsi_thread_set_force_reinstatement(conn) < 0) {
893 spin_unlock_bh(&conn->state_lock);
894 return;
897 atomic_set(&conn->connection_reinstatement, 1);
898 if (!sleep) {
899 spin_unlock_bh(&conn->state_lock);
900 return;
903 atomic_set(&conn->sleep_on_conn_wait_comp, 1);
904 spin_unlock_bh(&conn->state_lock);
906 wait_for_completion(&conn->conn_wait_comp);
907 complete(&conn->conn_post_wait_comp);
909 EXPORT_SYMBOL(iscsit_cause_connection_reinstatement);
911 void iscsit_fall_back_to_erl0(struct iscsi_session *sess)
913 pr_debug("Falling back to ErrorRecoveryLevel=0 for SID:"
914 " %u\n", sess->sid);
916 atomic_set(&sess->session_fall_back_to_erl0, 1);
919 static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn)
921 struct iscsi_session *sess = conn->sess;
923 if ((sess->sess_ops->ErrorRecoveryLevel == 2) &&
924 !atomic_read(&sess->session_reinstatement) &&
925 !atomic_read(&sess->session_fall_back_to_erl0))
926 iscsit_connection_recovery_transport_reset(conn);
927 else {
928 pr_debug("Performing cleanup for failed iSCSI"
929 " Connection ID: %hu from %s\n", conn->cid,
930 sess->sess_ops->InitiatorName);
931 iscsit_close_connection(conn);
935 void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
937 spin_lock_bh(&conn->state_lock);
938 if (atomic_read(&conn->connection_exit)) {
939 spin_unlock_bh(&conn->state_lock);
940 return;
942 atomic_set(&conn->connection_exit, 1);
944 if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) {
945 spin_unlock_bh(&conn->state_lock);
946 iscsit_close_connection(conn);
947 return;
950 if (conn->conn_state == TARG_CONN_STATE_CLEANUP_WAIT) {
951 spin_unlock_bh(&conn->state_lock);
952 return;
955 pr_debug("Moving to TARG_CONN_STATE_CLEANUP_WAIT.\n");
956 conn->conn_state = TARG_CONN_STATE_CLEANUP_WAIT;
957 spin_unlock_bh(&conn->state_lock);
959 iscsit_handle_connection_cleanup(conn);
963 * This is the simple function that makes the magic of
964 * sync and steering happen in the follow paradoxical order:
966 * 0) Receive conn->of_marker (bytes left until next OFMarker)
967 * bytes into an offload buffer. When we pass the exact number
968 * of bytes in conn->of_marker, iscsit_dump_data_payload() and hence
969 * rx_data() will automatically receive the identical u32 marker
970 * values and store it in conn->of_marker_offset;
971 * 1) Now conn->of_marker_offset will contain the offset to the start
972 * of the next iSCSI PDU. Dump these remaining bytes into another
973 * offload buffer.
974 * 2) We are done!
975 * Next byte in the TCP stream will contain the next iSCSI PDU!
976 * Cool Huh?!
978 int iscsit_recover_from_unknown_opcode(struct iscsi_conn *conn)
981 * Make sure the remaining bytes to next maker is a sane value.
983 if (conn->of_marker > (conn->conn_ops->OFMarkInt * 4)) {
984 pr_err("Remaining bytes to OFMarker: %u exceeds"
985 " OFMarkInt bytes: %u.\n", conn->of_marker,
986 conn->conn_ops->OFMarkInt * 4);
987 return -1;
990 pr_debug("Advancing %u bytes in TCP stream to get to the"
991 " next OFMarker.\n", conn->of_marker);
993 if (iscsit_dump_data_payload(conn, conn->of_marker, 0) < 0)
994 return -1;
997 * Make sure the offset marker we retrived is a valid value.
999 if (conn->of_marker_offset > (ISCSI_HDR_LEN + (ISCSI_CRC_LEN * 2) +
1000 conn->conn_ops->MaxRecvDataSegmentLength)) {
1001 pr_err("OfMarker offset value: %u exceeds limit.\n",
1002 conn->of_marker_offset);
1003 return -1;
1006 pr_debug("Discarding %u bytes of TCP stream to get to the"
1007 " next iSCSI Opcode.\n", conn->of_marker_offset);
1009 if (iscsit_dump_data_payload(conn, conn->of_marker_offset, 0) < 0)
1010 return -1;
1012 return 0;