]>
Commit | Line | Data |
---|---|---|
e48354ce NB |
1 | /******************************************************************************* |
2 | * This file contains the iSCSI Target DataIN value generation functions. | |
3 | * | |
4 | * \u00a9 Copyright 2007-2011 RisingTide Systems LLC. | |
5 | * | |
6 | * Licensed to the Linux Foundation under the General Public License (GPL) version 2. | |
7 | * | |
8 | * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License as published by | |
12 | * the Free Software Foundation; either version 2 of the License, or | |
13 | * (at your option) any later version. | |
14 | * | |
15 | * This program is distributed in the hope that it will be useful, | |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | * GNU General Public License for more details. | |
19 | ******************************************************************************/ | |
20 | ||
21 | #include <scsi/iscsi_proto.h> | |
22 | ||
23 | #include "iscsi_target_core.h" | |
24 | #include "iscsi_target_seq_pdu_list.h" | |
25 | #include "iscsi_target_erl1.h" | |
26 | #include "iscsi_target_util.h" | |
27 | #include "iscsi_target.h" | |
28 | #include "iscsi_target_datain_values.h" | |
29 | ||
30 | struct iscsi_datain_req *iscsit_allocate_datain_req(void) | |
31 | { | |
32 | struct iscsi_datain_req *dr; | |
33 | ||
34 | dr = kmem_cache_zalloc(lio_dr_cache, GFP_ATOMIC); | |
35 | if (!dr) { | |
36 | pr_err("Unable to allocate memory for" | |
37 | " struct iscsi_datain_req\n"); | |
38 | return NULL; | |
39 | } | |
8b1e1244 | 40 | INIT_LIST_HEAD(&dr->cmd_datain_node); |
e48354ce NB |
41 | |
42 | return dr; | |
43 | } | |
44 | ||
45 | void iscsit_attach_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr) | |
46 | { | |
47 | spin_lock(&cmd->datain_lock); | |
8b1e1244 | 48 | list_add_tail(&dr->cmd_datain_node, &cmd->datain_list); |
e48354ce NB |
49 | spin_unlock(&cmd->datain_lock); |
50 | } | |
51 | ||
52 | void iscsit_free_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr) | |
53 | { | |
54 | spin_lock(&cmd->datain_lock); | |
8b1e1244 | 55 | list_del(&dr->cmd_datain_node); |
e48354ce NB |
56 | spin_unlock(&cmd->datain_lock); |
57 | ||
58 | kmem_cache_free(lio_dr_cache, dr); | |
59 | } | |
60 | ||
61 | void iscsit_free_all_datain_reqs(struct iscsi_cmd *cmd) | |
62 | { | |
63 | struct iscsi_datain_req *dr, *dr_tmp; | |
64 | ||
65 | spin_lock(&cmd->datain_lock); | |
8b1e1244 AG |
66 | list_for_each_entry_safe(dr, dr_tmp, &cmd->datain_list, cmd_datain_node) { |
67 | list_del(&dr->cmd_datain_node); | |
e48354ce NB |
68 | kmem_cache_free(lio_dr_cache, dr); |
69 | } | |
70 | spin_unlock(&cmd->datain_lock); | |
71 | } | |
72 | ||
73 | struct iscsi_datain_req *iscsit_get_datain_req(struct iscsi_cmd *cmd) | |
74 | { | |
e48354ce NB |
75 | if (list_empty(&cmd->datain_list)) { |
76 | pr_err("cmd->datain_list is empty for ITT:" | |
77 | " 0x%08x\n", cmd->init_task_tag); | |
78 | return NULL; | |
79 | } | |
e48354ce | 80 | |
8b1e1244 AG |
81 | return list_first_entry(&cmd->datain_list, struct iscsi_datain_req, |
82 | cmd_datain_node); | |
e48354ce NB |
83 | } |
84 | ||
85 | /* | |
86 | * For Normal and Recovery DataSequenceInOrder=Yes and DataPDUInOrder=Yes. | |
87 | */ | |
88 | static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_yes( | |
89 | struct iscsi_cmd *cmd, | |
90 | struct iscsi_datain *datain) | |
91 | { | |
92 | u32 next_burst_len, read_data_done, read_data_left; | |
93 | struct iscsi_conn *conn = cmd->conn; | |
94 | struct iscsi_datain_req *dr; | |
95 | ||
96 | dr = iscsit_get_datain_req(cmd); | |
97 | if (!dr) | |
98 | return NULL; | |
99 | ||
100 | if (dr->recovery && dr->generate_recovery_values) { | |
101 | if (iscsit_create_recovery_datain_values_datasequenceinorder_yes( | |
102 | cmd, dr) < 0) | |
103 | return NULL; | |
104 | ||
105 | dr->generate_recovery_values = 0; | |
106 | } | |
107 | ||
108 | next_burst_len = (!dr->recovery) ? | |
109 | cmd->next_burst_len : dr->next_burst_len; | |
110 | read_data_done = (!dr->recovery) ? | |
111 | cmd->read_data_done : dr->read_data_done; | |
112 | ||
ebf1d95c | 113 | read_data_left = (cmd->se_cmd.data_length - read_data_done); |
e48354ce NB |
114 | if (!read_data_left) { |
115 | pr_err("ITT: 0x%08x read_data_left is zero!\n", | |
116 | cmd->init_task_tag); | |
117 | return NULL; | |
118 | } | |
119 | ||
120 | if ((read_data_left <= conn->conn_ops->MaxRecvDataSegmentLength) && | |
121 | (read_data_left <= (conn->sess->sess_ops->MaxBurstLength - | |
122 | next_burst_len))) { | |
123 | datain->length = read_data_left; | |
124 | ||
125 | datain->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS); | |
126 | if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) | |
127 | datain->flags |= ISCSI_FLAG_DATA_ACK; | |
128 | } else { | |
129 | if ((next_burst_len + | |
130 | conn->conn_ops->MaxRecvDataSegmentLength) < | |
131 | conn->sess->sess_ops->MaxBurstLength) { | |
132 | datain->length = | |
133 | conn->conn_ops->MaxRecvDataSegmentLength; | |
134 | next_burst_len += datain->length; | |
135 | } else { | |
136 | datain->length = (conn->sess->sess_ops->MaxBurstLength - | |
137 | next_burst_len); | |
138 | next_burst_len = 0; | |
139 | ||
140 | datain->flags |= ISCSI_FLAG_CMD_FINAL; | |
141 | if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) | |
142 | datain->flags |= ISCSI_FLAG_DATA_ACK; | |
143 | } | |
144 | } | |
145 | ||
146 | datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++; | |
147 | datain->offset = read_data_done; | |
148 | ||
149 | if (!dr->recovery) { | |
150 | cmd->next_burst_len = next_burst_len; | |
151 | cmd->read_data_done += datain->length; | |
152 | } else { | |
153 | dr->next_burst_len = next_burst_len; | |
154 | dr->read_data_done += datain->length; | |
155 | } | |
156 | ||
157 | if (!dr->recovery) { | |
158 | if (datain->flags & ISCSI_FLAG_DATA_STATUS) | |
159 | dr->dr_complete = DATAIN_COMPLETE_NORMAL; | |
160 | ||
161 | return dr; | |
162 | } | |
163 | ||
164 | if (!dr->runlength) { | |
165 | if (datain->flags & ISCSI_FLAG_DATA_STATUS) { | |
166 | dr->dr_complete = | |
167 | (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? | |
168 | DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : | |
169 | DATAIN_COMPLETE_CONNECTION_RECOVERY; | |
170 | } | |
171 | } else { | |
172 | if ((dr->begrun + dr->runlength) == dr->data_sn) { | |
173 | dr->dr_complete = | |
174 | (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? | |
175 | DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : | |
176 | DATAIN_COMPLETE_CONNECTION_RECOVERY; | |
177 | } | |
178 | } | |
179 | ||
180 | return dr; | |
181 | } | |
182 | ||
183 | /* | |
184 | * For Normal and Recovery DataSequenceInOrder=No and DataPDUInOrder=Yes. | |
185 | */ | |
186 | static struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes( | |
187 | struct iscsi_cmd *cmd, | |
188 | struct iscsi_datain *datain) | |
189 | { | |
190 | u32 offset, read_data_done, read_data_left, seq_send_order; | |
191 | struct iscsi_conn *conn = cmd->conn; | |
192 | struct iscsi_datain_req *dr; | |
193 | struct iscsi_seq *seq; | |
194 | ||
195 | dr = iscsit_get_datain_req(cmd); | |
196 | if (!dr) | |
197 | return NULL; | |
198 | ||
199 | if (dr->recovery && dr->generate_recovery_values) { | |
200 | if (iscsit_create_recovery_datain_values_datasequenceinorder_no( | |
201 | cmd, dr) < 0) | |
202 | return NULL; | |
203 | ||
204 | dr->generate_recovery_values = 0; | |
205 | } | |
206 | ||
207 | read_data_done = (!dr->recovery) ? | |
208 | cmd->read_data_done : dr->read_data_done; | |
209 | seq_send_order = (!dr->recovery) ? | |
210 | cmd->seq_send_order : dr->seq_send_order; | |
211 | ||
ebf1d95c | 212 | read_data_left = (cmd->se_cmd.data_length - read_data_done); |
e48354ce NB |
213 | if (!read_data_left) { |
214 | pr_err("ITT: 0x%08x read_data_left is zero!\n", | |
215 | cmd->init_task_tag); | |
216 | return NULL; | |
217 | } | |
218 | ||
219 | seq = iscsit_get_seq_holder_for_datain(cmd, seq_send_order); | |
220 | if (!seq) | |
221 | return NULL; | |
222 | ||
223 | seq->sent = 1; | |
224 | ||
225 | if (!dr->recovery && !seq->next_burst_len) | |
226 | seq->first_datasn = cmd->data_sn; | |
227 | ||
228 | offset = (seq->offset + seq->next_burst_len); | |
229 | ||
230 | if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >= | |
ebf1d95c AG |
231 | cmd->se_cmd.data_length) { |
232 | datain->length = (cmd->se_cmd.data_length - offset); | |
e48354ce NB |
233 | datain->offset = offset; |
234 | ||
235 | datain->flags |= ISCSI_FLAG_CMD_FINAL; | |
236 | if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) | |
237 | datain->flags |= ISCSI_FLAG_DATA_ACK; | |
238 | ||
239 | seq->next_burst_len = 0; | |
240 | seq_send_order++; | |
241 | } else { | |
242 | if ((seq->next_burst_len + | |
243 | conn->conn_ops->MaxRecvDataSegmentLength) < | |
244 | conn->sess->sess_ops->MaxBurstLength) { | |
245 | datain->length = | |
246 | conn->conn_ops->MaxRecvDataSegmentLength; | |
247 | datain->offset = (seq->offset + seq->next_burst_len); | |
248 | ||
249 | seq->next_burst_len += datain->length; | |
250 | } else { | |
251 | datain->length = (conn->sess->sess_ops->MaxBurstLength - | |
252 | seq->next_burst_len); | |
253 | datain->offset = (seq->offset + seq->next_burst_len); | |
254 | ||
255 | datain->flags |= ISCSI_FLAG_CMD_FINAL; | |
256 | if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) | |
257 | datain->flags |= ISCSI_FLAG_DATA_ACK; | |
258 | ||
259 | seq->next_burst_len = 0; | |
260 | seq_send_order++; | |
261 | } | |
262 | } | |
263 | ||
ebf1d95c | 264 | if ((read_data_done + datain->length) == cmd->se_cmd.data_length) |
e48354ce NB |
265 | datain->flags |= ISCSI_FLAG_DATA_STATUS; |
266 | ||
267 | datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++; | |
268 | if (!dr->recovery) { | |
269 | cmd->seq_send_order = seq_send_order; | |
270 | cmd->read_data_done += datain->length; | |
271 | } else { | |
272 | dr->seq_send_order = seq_send_order; | |
273 | dr->read_data_done += datain->length; | |
274 | } | |
275 | ||
276 | if (!dr->recovery) { | |
277 | if (datain->flags & ISCSI_FLAG_CMD_FINAL) | |
278 | seq->last_datasn = datain->data_sn; | |
279 | if (datain->flags & ISCSI_FLAG_DATA_STATUS) | |
280 | dr->dr_complete = DATAIN_COMPLETE_NORMAL; | |
281 | ||
282 | return dr; | |
283 | } | |
284 | ||
285 | if (!dr->runlength) { | |
286 | if (datain->flags & ISCSI_FLAG_DATA_STATUS) { | |
287 | dr->dr_complete = | |
288 | (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? | |
289 | DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : | |
290 | DATAIN_COMPLETE_CONNECTION_RECOVERY; | |
291 | } | |
292 | } else { | |
293 | if ((dr->begrun + dr->runlength) == dr->data_sn) { | |
294 | dr->dr_complete = | |
295 | (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? | |
296 | DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : | |
297 | DATAIN_COMPLETE_CONNECTION_RECOVERY; | |
298 | } | |
299 | } | |
300 | ||
301 | return dr; | |
302 | } | |
303 | ||
304 | /* | |
305 | * For Normal and Recovery DataSequenceInOrder=Yes and DataPDUInOrder=No. | |
306 | */ | |
307 | static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_no( | |
308 | struct iscsi_cmd *cmd, | |
309 | struct iscsi_datain *datain) | |
310 | { | |
311 | u32 next_burst_len, read_data_done, read_data_left; | |
312 | struct iscsi_conn *conn = cmd->conn; | |
313 | struct iscsi_datain_req *dr; | |
314 | struct iscsi_pdu *pdu; | |
315 | ||
316 | dr = iscsit_get_datain_req(cmd); | |
317 | if (!dr) | |
318 | return NULL; | |
319 | ||
320 | if (dr->recovery && dr->generate_recovery_values) { | |
321 | if (iscsit_create_recovery_datain_values_datasequenceinorder_yes( | |
322 | cmd, dr) < 0) | |
323 | return NULL; | |
324 | ||
325 | dr->generate_recovery_values = 0; | |
326 | } | |
327 | ||
328 | next_burst_len = (!dr->recovery) ? | |
329 | cmd->next_burst_len : dr->next_burst_len; | |
330 | read_data_done = (!dr->recovery) ? | |
331 | cmd->read_data_done : dr->read_data_done; | |
332 | ||
ebf1d95c | 333 | read_data_left = (cmd->se_cmd.data_length - read_data_done); |
e48354ce NB |
334 | if (!read_data_left) { |
335 | pr_err("ITT: 0x%08x read_data_left is zero!\n", | |
336 | cmd->init_task_tag); | |
337 | return dr; | |
338 | } | |
339 | ||
340 | pdu = iscsit_get_pdu_holder_for_seq(cmd, NULL); | |
341 | if (!pdu) | |
342 | return dr; | |
343 | ||
ebf1d95c | 344 | if ((read_data_done + pdu->length) == cmd->se_cmd.data_length) { |
e48354ce NB |
345 | pdu->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS); |
346 | if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) | |
347 | pdu->flags |= ISCSI_FLAG_DATA_ACK; | |
348 | ||
349 | next_burst_len = 0; | |
350 | } else { | |
351 | if ((next_burst_len + conn->conn_ops->MaxRecvDataSegmentLength) < | |
352 | conn->sess->sess_ops->MaxBurstLength) | |
353 | next_burst_len += pdu->length; | |
354 | else { | |
355 | pdu->flags |= ISCSI_FLAG_CMD_FINAL; | |
356 | if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) | |
357 | pdu->flags |= ISCSI_FLAG_DATA_ACK; | |
358 | ||
359 | next_burst_len = 0; | |
360 | } | |
361 | } | |
362 | ||
363 | pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++; | |
364 | if (!dr->recovery) { | |
365 | cmd->next_burst_len = next_burst_len; | |
366 | cmd->read_data_done += pdu->length; | |
367 | } else { | |
368 | dr->next_burst_len = next_burst_len; | |
369 | dr->read_data_done += pdu->length; | |
370 | } | |
371 | ||
372 | datain->flags = pdu->flags; | |
373 | datain->length = pdu->length; | |
374 | datain->offset = pdu->offset; | |
375 | datain->data_sn = pdu->data_sn; | |
376 | ||
377 | if (!dr->recovery) { | |
378 | if (datain->flags & ISCSI_FLAG_DATA_STATUS) | |
379 | dr->dr_complete = DATAIN_COMPLETE_NORMAL; | |
380 | ||
381 | return dr; | |
382 | } | |
383 | ||
384 | if (!dr->runlength) { | |
385 | if (datain->flags & ISCSI_FLAG_DATA_STATUS) { | |
386 | dr->dr_complete = | |
387 | (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? | |
388 | DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : | |
389 | DATAIN_COMPLETE_CONNECTION_RECOVERY; | |
390 | } | |
391 | } else { | |
392 | if ((dr->begrun + dr->runlength) == dr->data_sn) { | |
393 | dr->dr_complete = | |
394 | (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? | |
395 | DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : | |
396 | DATAIN_COMPLETE_CONNECTION_RECOVERY; | |
397 | } | |
398 | } | |
399 | ||
400 | return dr; | |
401 | } | |
402 | ||
403 | /* | |
404 | * For Normal and Recovery DataSequenceInOrder=No and DataPDUInOrder=No. | |
405 | */ | |
406 | static struct iscsi_datain_req *iscsit_set_datain_values_no_and_no( | |
407 | struct iscsi_cmd *cmd, | |
408 | struct iscsi_datain *datain) | |
409 | { | |
410 | u32 read_data_done, read_data_left, seq_send_order; | |
411 | struct iscsi_conn *conn = cmd->conn; | |
412 | struct iscsi_datain_req *dr; | |
413 | struct iscsi_pdu *pdu; | |
414 | struct iscsi_seq *seq = NULL; | |
415 | ||
416 | dr = iscsit_get_datain_req(cmd); | |
417 | if (!dr) | |
418 | return NULL; | |
419 | ||
420 | if (dr->recovery && dr->generate_recovery_values) { | |
421 | if (iscsit_create_recovery_datain_values_datasequenceinorder_no( | |
422 | cmd, dr) < 0) | |
423 | return NULL; | |
424 | ||
425 | dr->generate_recovery_values = 0; | |
426 | } | |
427 | ||
428 | read_data_done = (!dr->recovery) ? | |
429 | cmd->read_data_done : dr->read_data_done; | |
430 | seq_send_order = (!dr->recovery) ? | |
431 | cmd->seq_send_order : dr->seq_send_order; | |
432 | ||
ebf1d95c | 433 | read_data_left = (cmd->se_cmd.data_length - read_data_done); |
e48354ce NB |
434 | if (!read_data_left) { |
435 | pr_err("ITT: 0x%08x read_data_left is zero!\n", | |
436 | cmd->init_task_tag); | |
437 | return NULL; | |
438 | } | |
439 | ||
440 | seq = iscsit_get_seq_holder_for_datain(cmd, seq_send_order); | |
441 | if (!seq) | |
442 | return NULL; | |
443 | ||
444 | seq->sent = 1; | |
445 | ||
446 | if (!dr->recovery && !seq->next_burst_len) | |
447 | seq->first_datasn = cmd->data_sn; | |
448 | ||
449 | pdu = iscsit_get_pdu_holder_for_seq(cmd, seq); | |
450 | if (!pdu) | |
451 | return NULL; | |
452 | ||
453 | if (seq->pdu_send_order == seq->pdu_count) { | |
454 | pdu->flags |= ISCSI_FLAG_CMD_FINAL; | |
455 | if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) | |
456 | pdu->flags |= ISCSI_FLAG_DATA_ACK; | |
457 | ||
458 | seq->next_burst_len = 0; | |
459 | seq_send_order++; | |
460 | } else | |
461 | seq->next_burst_len += pdu->length; | |
462 | ||
ebf1d95c | 463 | if ((read_data_done + pdu->length) == cmd->se_cmd.data_length) |
e48354ce NB |
464 | pdu->flags |= ISCSI_FLAG_DATA_STATUS; |
465 | ||
466 | pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++; | |
467 | if (!dr->recovery) { | |
468 | cmd->seq_send_order = seq_send_order; | |
469 | cmd->read_data_done += pdu->length; | |
470 | } else { | |
471 | dr->seq_send_order = seq_send_order; | |
472 | dr->read_data_done += pdu->length; | |
473 | } | |
474 | ||
475 | datain->flags = pdu->flags; | |
476 | datain->length = pdu->length; | |
477 | datain->offset = pdu->offset; | |
478 | datain->data_sn = pdu->data_sn; | |
479 | ||
480 | if (!dr->recovery) { | |
481 | if (datain->flags & ISCSI_FLAG_CMD_FINAL) | |
482 | seq->last_datasn = datain->data_sn; | |
483 | if (datain->flags & ISCSI_FLAG_DATA_STATUS) | |
484 | dr->dr_complete = DATAIN_COMPLETE_NORMAL; | |
485 | ||
486 | return dr; | |
487 | } | |
488 | ||
489 | if (!dr->runlength) { | |
490 | if (datain->flags & ISCSI_FLAG_DATA_STATUS) { | |
491 | dr->dr_complete = | |
492 | (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? | |
493 | DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : | |
494 | DATAIN_COMPLETE_CONNECTION_RECOVERY; | |
495 | } | |
496 | } else { | |
497 | if ((dr->begrun + dr->runlength) == dr->data_sn) { | |
498 | dr->dr_complete = | |
499 | (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? | |
500 | DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : | |
501 | DATAIN_COMPLETE_CONNECTION_RECOVERY; | |
502 | } | |
503 | } | |
504 | ||
505 | return dr; | |
506 | } | |
507 | ||
508 | struct iscsi_datain_req *iscsit_get_datain_values( | |
509 | struct iscsi_cmd *cmd, | |
510 | struct iscsi_datain *datain) | |
511 | { | |
512 | struct iscsi_conn *conn = cmd->conn; | |
513 | ||
514 | if (conn->sess->sess_ops->DataSequenceInOrder && | |
515 | conn->sess->sess_ops->DataPDUInOrder) | |
516 | return iscsit_set_datain_values_yes_and_yes(cmd, datain); | |
517 | else if (!conn->sess->sess_ops->DataSequenceInOrder && | |
518 | conn->sess->sess_ops->DataPDUInOrder) | |
519 | return iscsit_set_datain_values_no_and_yes(cmd, datain); | |
520 | else if (conn->sess->sess_ops->DataSequenceInOrder && | |
521 | !conn->sess->sess_ops->DataPDUInOrder) | |
522 | return iscsit_set_datain_values_yes_and_no(cmd, datain); | |
523 | else if (!conn->sess->sess_ops->DataSequenceInOrder && | |
524 | !conn->sess->sess_ops->DataPDUInOrder) | |
525 | return iscsit_set_datain_values_no_and_no(cmd, datain); | |
526 | ||
527 | return NULL; | |
528 | } |