1 /*******************************************************************************
2  * This file contains main functions related to iSCSI DataSequenceInOrder=No
3  * and DataPDUInOrder=No.
4  *
5  * (c) Copyright 2007-2013 Datera, Inc.
6  *
7  * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
8  *
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.
13  *
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  ******************************************************************************/
19 
20 #include <linux/slab.h>
21 #include <linux/random.h>
22 
23 #include <target/iscsi/iscsi_target_core.h>
24 #include "iscsi_target_util.h"
25 #include "iscsi_target_tpg.h"
26 #include "iscsi_target_seq_pdu_list.h"
27 
28 #ifdef DEBUG
29 static void iscsit_dump_seq_list(struct iscsi_cmd *cmd)
30 {
31 	int i;
32 	struct iscsi_seq *seq;
33 
34 	pr_debug("Dumping Sequence List for ITT: 0x%08x:\n",
35 			cmd->init_task_tag);
36 
37 	for (i = 0; i < cmd->seq_count; i++) {
38 		seq = &cmd->seq_list[i];
39 		pr_debug("i: %d, pdu_start: %d, pdu_count: %d,"
40 			" offset: %d, xfer_len: %d, seq_send_order: %d,"
41 			" seq_no: %d\n", i, seq->pdu_start, seq->pdu_count,
42 			seq->offset, seq->xfer_len, seq->seq_send_order,
43 			seq->seq_no);
44 	}
45 }
46 
47 static void iscsit_dump_pdu_list(struct iscsi_cmd *cmd)
48 {
49 	int i;
50 	struct iscsi_pdu *pdu;
51 
52 	pr_debug("Dumping PDU List for ITT: 0x%08x:\n",
53 			cmd->init_task_tag);
54 
55 	for (i = 0; i < cmd->pdu_count; i++) {
56 		pdu = &cmd->pdu_list[i];
57 		pr_debug("i: %d, offset: %d, length: %d,"
58 			" pdu_send_order: %d, seq_no: %d\n", i, pdu->offset,
59 			pdu->length, pdu->pdu_send_order, pdu->seq_no);
60 	}
61 }
62 #else
63 static void iscsit_dump_seq_list(struct iscsi_cmd *cmd) {}
64 static void iscsit_dump_pdu_list(struct iscsi_cmd *cmd) {}
65 #endif
66 
67 static void iscsit_ordered_seq_lists(
68 	struct iscsi_cmd *cmd,
69 	u8 type)
70 {
71 	u32 i, seq_count = 0;
72 
73 	for (i = 0; i < cmd->seq_count; i++) {
74 		if (cmd->seq_list[i].type != SEQTYPE_NORMAL)
75 			continue;
76 		cmd->seq_list[i].seq_send_order = seq_count++;
77 	}
78 }
79 
80 static void iscsit_ordered_pdu_lists(
81 	struct iscsi_cmd *cmd,
82 	u8 type)
83 {
84 	u32 i, pdu_send_order = 0, seq_no = 0;
85 
86 	for (i = 0; i < cmd->pdu_count; i++) {
87 redo:
88 		if (cmd->pdu_list[i].seq_no == seq_no) {
89 			cmd->pdu_list[i].pdu_send_order = pdu_send_order++;
90 			continue;
91 		}
92 		seq_no++;
93 		pdu_send_order = 0;
94 		goto redo;
95 	}
96 }
97 
98 /*
99  *	Generate count random values into array.
100  *	Use 0x80000000 to mark generates valued in array[].
101  */
102 static void iscsit_create_random_array(u32 *array, u32 count)
103 {
104 	int i, j, k;
105 
106 	if (count == 1) {
107 		array[0] = 0;
108 		return;
109 	}
110 
111 	for (i = 0; i < count; i++) {
112 redo:
113 		get_random_bytes(&j, sizeof(u32));
114 		j = (1 + (int) (9999 + 1) - j) % count;
115 		for (k = 0; k < i + 1; k++) {
116 			j |= 0x80000000;
117 			if ((array[k] & 0x80000000) && (array[k] == j))
118 				goto redo;
119 		}
120 		array[i] = j;
121 	}
122 
123 	for (i = 0; i < count; i++)
124 		array[i] &= ~0x80000000;
125 }
126 
127 static int iscsit_randomize_pdu_lists(
128 	struct iscsi_cmd *cmd,
129 	u8 type)
130 {
131 	int i = 0;
132 	u32 *array, pdu_count, seq_count = 0, seq_no = 0, seq_offset = 0;
133 
134 	for (pdu_count = 0; pdu_count < cmd->pdu_count; pdu_count++) {
135 redo:
136 		if (cmd->pdu_list[pdu_count].seq_no == seq_no) {
137 			seq_count++;
138 			continue;
139 		}
140 		array = kcalloc(seq_count, sizeof(u32), GFP_KERNEL);
141 		if (!array) {
142 			pr_err("Unable to allocate memory"
143 				" for random array.\n");
144 			return -ENOMEM;
145 		}
146 		iscsit_create_random_array(array, seq_count);
147 
148 		for (i = 0; i < seq_count; i++)
149 			cmd->pdu_list[seq_offset+i].pdu_send_order = array[i];
150 
151 		kfree(array);
152 
153 		seq_offset += seq_count;
154 		seq_count = 0;
155 		seq_no++;
156 		goto redo;
157 	}
158 
159 	if (seq_count) {
160 		array = kcalloc(seq_count, sizeof(u32), GFP_KERNEL);
161 		if (!array) {
162 			pr_err("Unable to allocate memory for"
163 				" random array.\n");
164 			return -ENOMEM;
165 		}
166 		iscsit_create_random_array(array, seq_count);
167 
168 		for (i = 0; i < seq_count; i++)
169 			cmd->pdu_list[seq_offset+i].pdu_send_order = array[i];
170 
171 		kfree(array);
172 	}
173 
174 	return 0;
175 }
176 
177 static int iscsit_randomize_seq_lists(
178 	struct iscsi_cmd *cmd,
179 	u8 type)
180 {
181 	int i, j = 0;
182 	u32 *array, seq_count = cmd->seq_count;
183 
184 	if ((type == PDULIST_IMMEDIATE) || (type == PDULIST_UNSOLICITED))
185 		seq_count--;
186 	else if (type == PDULIST_IMMEDIATE_AND_UNSOLICITED)
187 		seq_count -= 2;
188 
189 	if (!seq_count)
190 		return 0;
191 
192 	array = kcalloc(seq_count, sizeof(u32), GFP_KERNEL);
193 	if (!array) {
194 		pr_err("Unable to allocate memory for random array.\n");
195 		return -ENOMEM;
196 	}
197 	iscsit_create_random_array(array, seq_count);
198 
199 	for (i = 0; i < cmd->seq_count; i++) {
200 		if (cmd->seq_list[i].type != SEQTYPE_NORMAL)
201 			continue;
202 		cmd->seq_list[i].seq_send_order = array[j++];
203 	}
204 
205 	kfree(array);
206 	return 0;
207 }
208 
209 static void iscsit_determine_counts_for_list(
210 	struct iscsi_cmd *cmd,
211 	struct iscsi_build_list *bl,
212 	u32 *seq_count,
213 	u32 *pdu_count)
214 {
215 	int check_immediate = 0;
216 	u32 burstlength = 0, offset = 0;
217 	u32 unsolicited_data_length = 0;
218 	u32 mdsl;
219 	struct iscsi_conn *conn = cmd->conn;
220 
221 	if (cmd->se_cmd.data_direction == DMA_TO_DEVICE)
222 		mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength;
223 	else
224 		mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength;
225 
226 	if ((bl->type == PDULIST_IMMEDIATE) ||
227 	    (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
228 		check_immediate = 1;
229 
230 	if ((bl->type == PDULIST_UNSOLICITED) ||
231 	    (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
232 		unsolicited_data_length = min(cmd->se_cmd.data_length,
233 			conn->sess->sess_ops->FirstBurstLength);
234 
235 	while (offset < cmd->se_cmd.data_length) {
236 		*pdu_count += 1;
237 
238 		if (check_immediate) {
239 			check_immediate = 0;
240 			offset += bl->immediate_data_length;
241 			*seq_count += 1;
242 			if (unsolicited_data_length)
243 				unsolicited_data_length -=
244 					bl->immediate_data_length;
245 			continue;
246 		}
247 		if (unsolicited_data_length > 0) {
248 			if ((offset + mdsl) >= cmd->se_cmd.data_length) {
249 				unsolicited_data_length -=
250 					(cmd->se_cmd.data_length - offset);
251 				offset += (cmd->se_cmd.data_length - offset);
252 				continue;
253 			}
254 			if ((offset + mdsl)
255 					>= conn->sess->sess_ops->FirstBurstLength) {
256 				unsolicited_data_length -=
257 					(conn->sess->sess_ops->FirstBurstLength -
258 					offset);
259 				offset += (conn->sess->sess_ops->FirstBurstLength -
260 					offset);
261 				burstlength = 0;
262 				*seq_count += 1;
263 				continue;
264 			}
265 
266 			offset += mdsl;
267 			unsolicited_data_length -= mdsl;
268 			continue;
269 		}
270 		if ((offset + mdsl) >= cmd->se_cmd.data_length) {
271 			offset += (cmd->se_cmd.data_length - offset);
272 			continue;
273 		}
274 		if ((burstlength + mdsl) >=
275 		     conn->sess->sess_ops->MaxBurstLength) {
276 			offset += (conn->sess->sess_ops->MaxBurstLength -
277 					burstlength);
278 			burstlength = 0;
279 			*seq_count += 1;
280 			continue;
281 		}
282 
283 		burstlength += mdsl;
284 		offset += mdsl;
285 	}
286 }
287 
288 
289 /*
290  *	Builds PDU and/or Sequence list, called while DataSequenceInOrder=No
291  *	or DataPDUInOrder=No.
292  */
293 static int iscsit_do_build_pdu_and_seq_lists(
294 	struct iscsi_cmd *cmd,
295 	struct iscsi_build_list *bl)
296 {
297 	int check_immediate = 0, datapduinorder, datasequenceinorder;
298 	u32 burstlength = 0, offset = 0, i = 0, mdsl;
299 	u32 pdu_count = 0, seq_no = 0, unsolicited_data_length = 0;
300 	struct iscsi_conn *conn = cmd->conn;
301 	struct iscsi_pdu *pdu = cmd->pdu_list;
302 	struct iscsi_seq *seq = cmd->seq_list;
303 
304 	if (cmd->se_cmd.data_direction == DMA_TO_DEVICE)
305 		mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength;
306 	else
307 		mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength;
308 
309 	datapduinorder = conn->sess->sess_ops->DataPDUInOrder;
310 	datasequenceinorder = conn->sess->sess_ops->DataSequenceInOrder;
311 
312 	if ((bl->type == PDULIST_IMMEDIATE) ||
313 	    (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
314 		check_immediate = 1;
315 
316 	if ((bl->type == PDULIST_UNSOLICITED) ||
317 	    (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
318 		unsolicited_data_length = min(cmd->se_cmd.data_length,
319 			conn->sess->sess_ops->FirstBurstLength);
320 
321 	while (offset < cmd->se_cmd.data_length) {
322 		pdu_count++;
323 		if (!datapduinorder) {
324 			pdu[i].offset = offset;
325 			pdu[i].seq_no = seq_no;
326 		}
327 		if (!datasequenceinorder && (pdu_count == 1)) {
328 			seq[seq_no].pdu_start = i;
329 			seq[seq_no].seq_no = seq_no;
330 			seq[seq_no].offset = offset;
331 			seq[seq_no].orig_offset = offset;
332 		}
333 
334 		if (check_immediate) {
335 			check_immediate = 0;
336 			if (!datapduinorder) {
337 				pdu[i].type = PDUTYPE_IMMEDIATE;
338 				pdu[i++].length = bl->immediate_data_length;
339 			}
340 			if (!datasequenceinorder) {
341 				seq[seq_no].type = SEQTYPE_IMMEDIATE;
342 				seq[seq_no].pdu_count = 1;
343 				seq[seq_no].xfer_len =
344 					bl->immediate_data_length;
345 			}
346 			offset += bl->immediate_data_length;
347 			pdu_count = 0;
348 			seq_no++;
349 			if (unsolicited_data_length)
350 				unsolicited_data_length -=
351 					bl->immediate_data_length;
352 			continue;
353 		}
354 		if (unsolicited_data_length > 0) {
355 			if ((offset + mdsl) >= cmd->se_cmd.data_length) {
356 				if (!datapduinorder) {
357 					pdu[i].type = PDUTYPE_UNSOLICITED;
358 					pdu[i].length =
359 						(cmd->se_cmd.data_length - offset);
360 				}
361 				if (!datasequenceinorder) {
362 					seq[seq_no].type = SEQTYPE_UNSOLICITED;
363 					seq[seq_no].pdu_count = pdu_count;
364 					seq[seq_no].xfer_len = (burstlength +
365 						(cmd->se_cmd.data_length - offset));
366 				}
367 				unsolicited_data_length -=
368 						(cmd->se_cmd.data_length - offset);
369 				offset += (cmd->se_cmd.data_length - offset);
370 				continue;
371 			}
372 			if ((offset + mdsl) >=
373 					conn->sess->sess_ops->FirstBurstLength) {
374 				if (!datapduinorder) {
375 					pdu[i].type = PDUTYPE_UNSOLICITED;
376 					pdu[i++].length =
377 					   (conn->sess->sess_ops->FirstBurstLength -
378 						offset);
379 				}
380 				if (!datasequenceinorder) {
381 					seq[seq_no].type = SEQTYPE_UNSOLICITED;
382 					seq[seq_no].pdu_count = pdu_count;
383 					seq[seq_no].xfer_len = (burstlength +
384 					   (conn->sess->sess_ops->FirstBurstLength -
385 						offset));
386 				}
387 				unsolicited_data_length -=
388 					(conn->sess->sess_ops->FirstBurstLength -
389 						offset);
390 				offset += (conn->sess->sess_ops->FirstBurstLength -
391 						offset);
392 				burstlength = 0;
393 				pdu_count = 0;
394 				seq_no++;
395 				continue;
396 			}
397 
398 			if (!datapduinorder) {
399 				pdu[i].type = PDUTYPE_UNSOLICITED;
400 				pdu[i++].length = mdsl;
401 			}
402 			burstlength += mdsl;
403 			offset += mdsl;
404 			unsolicited_data_length -= mdsl;
405 			continue;
406 		}
407 		if ((offset + mdsl) >= cmd->se_cmd.data_length) {
408 			if (!datapduinorder) {
409 				pdu[i].type = PDUTYPE_NORMAL;
410 				pdu[i].length = (cmd->se_cmd.data_length - offset);
411 			}
412 			if (!datasequenceinorder) {
413 				seq[seq_no].type = SEQTYPE_NORMAL;
414 				seq[seq_no].pdu_count = pdu_count;
415 				seq[seq_no].xfer_len = (burstlength +
416 					(cmd->se_cmd.data_length - offset));
417 			}
418 			offset += (cmd->se_cmd.data_length - offset);
419 			continue;
420 		}
421 		if ((burstlength + mdsl) >=
422 		     conn->sess->sess_ops->MaxBurstLength) {
423 			if (!datapduinorder) {
424 				pdu[i].type = PDUTYPE_NORMAL;
425 				pdu[i++].length =
426 					(conn->sess->sess_ops->MaxBurstLength -
427 						burstlength);
428 			}
429 			if (!datasequenceinorder) {
430 				seq[seq_no].type = SEQTYPE_NORMAL;
431 				seq[seq_no].pdu_count = pdu_count;
432 				seq[seq_no].xfer_len = (burstlength +
433 					(conn->sess->sess_ops->MaxBurstLength -
434 					burstlength));
435 			}
436 			offset += (conn->sess->sess_ops->MaxBurstLength -
437 					burstlength);
438 			burstlength = 0;
439 			pdu_count = 0;
440 			seq_no++;
441 			continue;
442 		}
443 
444 		if (!datapduinorder) {
445 			pdu[i].type = PDUTYPE_NORMAL;
446 			pdu[i++].length = mdsl;
447 		}
448 		burstlength += mdsl;
449 		offset += mdsl;
450 	}
451 
452 	if (!datasequenceinorder) {
453 		if (bl->data_direction & ISCSI_PDU_WRITE) {
454 			if (bl->randomize & RANDOM_R2T_OFFSETS) {
455 				if (iscsit_randomize_seq_lists(cmd, bl->type)
456 						< 0)
457 					return -1;
458 			} else
459 				iscsit_ordered_seq_lists(cmd, bl->type);
460 		} else if (bl->data_direction & ISCSI_PDU_READ) {
461 			if (bl->randomize & RANDOM_DATAIN_SEQ_OFFSETS) {
462 				if (iscsit_randomize_seq_lists(cmd, bl->type)
463 						< 0)
464 					return -1;
465 			} else
466 				iscsit_ordered_seq_lists(cmd, bl->type);
467 		}
468 
469 		iscsit_dump_seq_list(cmd);
470 	}
471 	if (!datapduinorder) {
472 		if (bl->data_direction & ISCSI_PDU_WRITE) {
473 			if (bl->randomize & RANDOM_DATAOUT_PDU_OFFSETS) {
474 				if (iscsit_randomize_pdu_lists(cmd, bl->type)
475 						< 0)
476 					return -1;
477 			} else
478 				iscsit_ordered_pdu_lists(cmd, bl->type);
479 		} else if (bl->data_direction & ISCSI_PDU_READ) {
480 			if (bl->randomize & RANDOM_DATAIN_PDU_OFFSETS) {
481 				if (iscsit_randomize_pdu_lists(cmd, bl->type)
482 						< 0)
483 					return -1;
484 			} else
485 				iscsit_ordered_pdu_lists(cmd, bl->type);
486 		}
487 
488 		iscsit_dump_pdu_list(cmd);
489 	}
490 
491 	return 0;
492 }
493 
494 int iscsit_build_pdu_and_seq_lists(
495 	struct iscsi_cmd *cmd,
496 	u32 immediate_data_length)
497 {
498 	struct iscsi_build_list bl;
499 	u32 pdu_count = 0, seq_count = 1;
500 	struct iscsi_conn *conn = cmd->conn;
501 	struct iscsi_pdu *pdu = NULL;
502 	struct iscsi_seq *seq = NULL;
503 
504 	struct iscsi_session *sess = conn->sess;
505 	struct iscsi_node_attrib *na;
506 
507 	/*
508 	 * Do nothing if no OOO shenanigans
509 	 */
510 	if (sess->sess_ops->DataSequenceInOrder &&
511 	    sess->sess_ops->DataPDUInOrder)
512 		return 0;
513 
514 	if (cmd->data_direction == DMA_NONE)
515 		return 0;
516 
517 	na = iscsit_tpg_get_node_attrib(sess);
518 	memset(&bl, 0, sizeof(struct iscsi_build_list));
519 
520 	if (cmd->data_direction == DMA_FROM_DEVICE) {
521 		bl.data_direction = ISCSI_PDU_READ;
522 		bl.type = PDULIST_NORMAL;
523 		if (na->random_datain_pdu_offsets)
524 			bl.randomize |= RANDOM_DATAIN_PDU_OFFSETS;
525 		if (na->random_datain_seq_offsets)
526 			bl.randomize |= RANDOM_DATAIN_SEQ_OFFSETS;
527 	} else {
528 		bl.data_direction = ISCSI_PDU_WRITE;
529 		bl.immediate_data_length = immediate_data_length;
530 		if (na->random_r2t_offsets)
531 			bl.randomize |= RANDOM_R2T_OFFSETS;
532 
533 		if (!cmd->immediate_data && !cmd->unsolicited_data)
534 			bl.type = PDULIST_NORMAL;
535 		else if (cmd->immediate_data && !cmd->unsolicited_data)
536 			bl.type = PDULIST_IMMEDIATE;
537 		else if (!cmd->immediate_data && cmd->unsolicited_data)
538 			bl.type = PDULIST_UNSOLICITED;
539 		else if (cmd->immediate_data && cmd->unsolicited_data)
540 			bl.type = PDULIST_IMMEDIATE_AND_UNSOLICITED;
541 	}
542 
543 	iscsit_determine_counts_for_list(cmd, &bl, &seq_count, &pdu_count);
544 
545 	if (!conn->sess->sess_ops->DataSequenceInOrder) {
546 		seq = kcalloc(seq_count, sizeof(struct iscsi_seq), GFP_ATOMIC);
547 		if (!seq) {
548 			pr_err("Unable to allocate struct iscsi_seq list\n");
549 			return -ENOMEM;
550 		}
551 		cmd->seq_list = seq;
552 		cmd->seq_count = seq_count;
553 	}
554 
555 	if (!conn->sess->sess_ops->DataPDUInOrder) {
556 		pdu = kcalloc(pdu_count, sizeof(struct iscsi_pdu), GFP_ATOMIC);
557 		if (!pdu) {
558 			pr_err("Unable to allocate struct iscsi_pdu list.\n");
559 			kfree(seq);
560 			return -ENOMEM;
561 		}
562 		cmd->pdu_list = pdu;
563 		cmd->pdu_count = pdu_count;
564 	}
565 
566 	return iscsit_do_build_pdu_and_seq_lists(cmd, &bl);
567 }
568 
569 struct iscsi_pdu *iscsit_get_pdu_holder(
570 	struct iscsi_cmd *cmd,
571 	u32 offset,
572 	u32 length)
573 {
574 	u32 i;
575 	struct iscsi_pdu *pdu = NULL;
576 
577 	if (!cmd->pdu_list) {
578 		pr_err("struct iscsi_cmd->pdu_list is NULL!\n");
579 		return NULL;
580 	}
581 
582 	pdu = &cmd->pdu_list[0];
583 
584 	for (i = 0; i < cmd->pdu_count; i++)
585 		if ((pdu[i].offset == offset) && (pdu[i].length == length))
586 			return &pdu[i];
587 
588 	pr_err("Unable to locate PDU holder for ITT: 0x%08x, Offset:"
589 		" %u, Length: %u\n", cmd->init_task_tag, offset, length);
590 	return NULL;
591 }
592 
593 struct iscsi_pdu *iscsit_get_pdu_holder_for_seq(
594 	struct iscsi_cmd *cmd,
595 	struct iscsi_seq *seq)
596 {
597 	u32 i;
598 	struct iscsi_conn *conn = cmd->conn;
599 	struct iscsi_pdu *pdu = NULL;
600 
601 	if (!cmd->pdu_list) {
602 		pr_err("struct iscsi_cmd->pdu_list is NULL!\n");
603 		return NULL;
604 	}
605 
606 	if (conn->sess->sess_ops->DataSequenceInOrder) {
607 redo:
608 		pdu = &cmd->pdu_list[cmd->pdu_start];
609 
610 		for (i = 0; pdu[i].seq_no != cmd->seq_no; i++) {
611 			pr_debug("pdu[i].seq_no: %d, pdu[i].pdu"
612 				"_send_order: %d, pdu[i].offset: %d,"
613 				" pdu[i].length: %d\n", pdu[i].seq_no,
614 				pdu[i].pdu_send_order, pdu[i].offset,
615 				pdu[i].length);
616 
617 			if (pdu[i].pdu_send_order == cmd->pdu_send_order) {
618 				cmd->pdu_send_order++;
619 				return &pdu[i];
620 			}
621 		}
622 
623 		cmd->pdu_start += cmd->pdu_send_order;
624 		cmd->pdu_send_order = 0;
625 		cmd->seq_no++;
626 
627 		if (cmd->pdu_start < cmd->pdu_count)
628 			goto redo;
629 
630 		pr_err("Command ITT: 0x%08x unable to locate"
631 			" struct iscsi_pdu for cmd->pdu_send_order: %u.\n",
632 			cmd->init_task_tag, cmd->pdu_send_order);
633 		return NULL;
634 	} else {
635 		if (!seq) {
636 			pr_err("struct iscsi_seq is NULL!\n");
637 			return NULL;
638 		}
639 
640 		pr_debug("seq->pdu_start: %d, seq->pdu_count: %d,"
641 			" seq->seq_no: %d\n", seq->pdu_start, seq->pdu_count,
642 			seq->seq_no);
643 
644 		pdu = &cmd->pdu_list[seq->pdu_start];
645 
646 		if (seq->pdu_send_order == seq->pdu_count) {
647 			pr_err("Command ITT: 0x%08x seq->pdu_send"
648 				"_order: %u equals seq->pdu_count: %u\n",
649 				cmd->init_task_tag, seq->pdu_send_order,
650 				seq->pdu_count);
651 			return NULL;
652 		}
653 
654 		for (i = 0; i < seq->pdu_count; i++) {
655 			if (pdu[i].pdu_send_order == seq->pdu_send_order) {
656 				seq->pdu_send_order++;
657 				return &pdu[i];
658 			}
659 		}
660 
661 		pr_err("Command ITT: 0x%08x unable to locate iscsi"
662 			"_pdu_t for seq->pdu_send_order: %u.\n",
663 			cmd->init_task_tag, seq->pdu_send_order);
664 		return NULL;
665 	}
666 
667 	return NULL;
668 }
669 
670 struct iscsi_seq *iscsit_get_seq_holder(
671 	struct iscsi_cmd *cmd,
672 	u32 offset,
673 	u32 length)
674 {
675 	u32 i;
676 
677 	if (!cmd->seq_list) {
678 		pr_err("struct iscsi_cmd->seq_list is NULL!\n");
679 		return NULL;
680 	}
681 
682 	for (i = 0; i < cmd->seq_count; i++) {
683 		pr_debug("seq_list[i].orig_offset: %d, seq_list[i]."
684 			"xfer_len: %d, seq_list[i].seq_no %u\n",
685 			cmd->seq_list[i].orig_offset, cmd->seq_list[i].xfer_len,
686 			cmd->seq_list[i].seq_no);
687 
688 		if ((cmd->seq_list[i].orig_offset +
689 				cmd->seq_list[i].xfer_len) >=
690 				(offset + length))
691 			return &cmd->seq_list[i];
692 	}
693 
694 	pr_err("Unable to locate Sequence holder for ITT: 0x%08x,"
695 		" Offset: %u, Length: %u\n", cmd->init_task_tag, offset,
696 		length);
697 	return NULL;
698 }
699