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