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