1 /*
2 Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #ifdef HAVE_SYS_TYPES_H
22 #include <sys/types.h>
23 #endif
24
25 #ifdef HAVE_ARPA_INET_H
26 #include <arpa/inet.h>
27 #endif
28
29 #if defined(_WIN32)
30 #include <winsock2.h>
31 #endif
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "iscsi.h"
37 #include "iscsi-private.h"
38 #include "scsi-lowlevel.h"
39 #include "slist.h"
40
41 static void
iscsi_scsi_response_cb(struct iscsi_context * iscsi,int status,void * command_data _U_,void * private_data)42 iscsi_scsi_response_cb(struct iscsi_context *iscsi, int status,
43 void *command_data _U_, void *private_data)
44 {
45 struct iscsi_scsi_cbdata *scsi_cbdata =
46 (struct iscsi_scsi_cbdata *)private_data;
47
48 switch (status) {
49 case SCSI_STATUS_RESERVATION_CONFLICT:
50 case SCSI_STATUS_CHECK_CONDITION:
51 case SCSI_STATUS_GOOD:
52 case SCSI_STATUS_BUSY:
53 case SCSI_STATUS_CONDITION_MET:
54 case SCSI_STATUS_TASK_SET_FULL:
55 case SCSI_STATUS_ACA_ACTIVE:
56 case SCSI_STATUS_TASK_ABORTED:
57 case SCSI_STATUS_ERROR:
58 case SCSI_STATUS_CANCELLED:
59 case SCSI_STATUS_TIMEOUT:
60 scsi_cbdata->task->status = status;
61 if (scsi_cbdata->callback) {
62 scsi_cbdata->callback(iscsi, status, scsi_cbdata->task,
63 scsi_cbdata->private_data);
64 }
65 return;
66 default:
67 scsi_cbdata->task->status = SCSI_STATUS_ERROR;
68 iscsi_set_error(iscsi, "Cant handle scsi status %d yet.",
69 status);
70 if (scsi_cbdata->callback) {
71 scsi_cbdata->callback(iscsi, SCSI_STATUS_ERROR, scsi_cbdata->task,
72 scsi_cbdata->private_data);
73 }
74 }
75 }
76
77 static int
iscsi_send_data_out(struct iscsi_context * iscsi,struct iscsi_pdu * cmd_pdu,uint32_t ttt,uint32_t offset,uint32_t tot_len)78 iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu,
79 uint32_t ttt, uint32_t offset, uint32_t tot_len)
80 {
81 while (tot_len > 0) {
82 uint32_t len = tot_len;
83 struct iscsi_pdu *pdu;
84 int flags;
85
86 len = MIN(len, iscsi->target_max_recv_data_segment_length);
87
88 pdu = iscsi_allocate_pdu(iscsi,
89 ISCSI_PDU_DATA_OUT,
90 ISCSI_PDU_NO_PDU,
91 cmd_pdu->itt,
92 ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_DELETE_WHEN_SENT);
93 if (pdu == NULL) {
94 iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate "
95 "scsi data out pdu.");
96 goto error;
97 }
98 pdu->scsi_cbdata.task = cmd_pdu->scsi_cbdata.task;
99 /* set the cmdsn in the pdu struct so we can compare with
100 * maxcmdsn when sending to socket even if data-out pdus
101 * do not carry a cmdsn on the wire */
102 pdu->cmdsn = cmd_pdu->cmdsn;
103
104 if (tot_len == len) {
105 flags = ISCSI_PDU_SCSI_FINAL;
106 } else {
107 flags = 0;
108 }
109
110 /* flags */
111 iscsi_pdu_set_pduflags(pdu, flags);
112
113 /* lun */
114 iscsi_pdu_set_lun(pdu, cmd_pdu->lun);
115
116 /* ttt */
117 iscsi_pdu_set_ttt(pdu, ttt);
118
119 /* data sn */
120 iscsi_pdu_set_datasn(pdu, cmd_pdu->datasn++);
121
122 /* buffer offset */
123 iscsi_pdu_set_bufferoffset(pdu, offset);
124
125 pdu->payload_offset = offset;
126 pdu->payload_len = len;
127
128 /* update data segment length */
129 scsi_set_uint32(&pdu->outdata.data[4], pdu->payload_len);
130
131 if (iscsi_queue_pdu(iscsi, pdu) != 0) {
132 iscsi_set_error(iscsi, "Out-of-memory: failed to queue iscsi "
133 "scsi pdu.");
134 goto error;
135 }
136
137 tot_len -= len;
138 offset += len;
139 }
140 return 0;
141
142 error:
143 ISCSI_LIST_REMOVE(&iscsi->outqueue, cmd_pdu);
144 ISCSI_LIST_REMOVE(&iscsi->waitpdu, cmd_pdu);
145 if (cmd_pdu->callback) {
146 cmd_pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
147 cmd_pdu->private_data);
148 }
149 iscsi->drv->free_pdu(iscsi, cmd_pdu);
150 return -1;
151 }
152
153 static int
iscsi_send_unsolicited_data_out(struct iscsi_context * iscsi,struct iscsi_pdu * pdu)154 iscsi_send_unsolicited_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
155 {
156 uint32_t len = MIN(pdu->expxferlen, iscsi->first_burst_length) - pdu->payload_len;
157
158 return iscsi_send_data_out(iscsi, pdu, 0xffffffff,
159 pdu->payload_len, len);
160 }
161
162 /* Using 'struct iscsi_data *d' for data-out is optional
163 * and will be converted into a one element data-out iovector.
164 */
165 int
iscsi_scsi_command_async(struct iscsi_context * iscsi,int lun,struct scsi_task * task,iscsi_command_cb cb,struct iscsi_data * d,void * private_data)166 iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun,
167 struct scsi_task *task, iscsi_command_cb cb,
168 struct iscsi_data *d, void *private_data)
169 {
170 struct iscsi_pdu *pdu;
171 int flags;
172
173 if (iscsi->old_iscsi) {
174 iscsi = iscsi->old_iscsi;
175 ISCSI_LOG(iscsi, 2, "iscsi_scsi_command_async: queuing cmd to old_iscsi while reconnecting");
176 }
177
178 if (iscsi->session_type != ISCSI_SESSION_NORMAL) {
179 iscsi_set_error(iscsi, "Trying to send command on "
180 "discovery session.");
181 return -1;
182 }
183
184 if (iscsi->is_loggedin == 0 && !iscsi->pending_reconnect) {
185 iscsi_set_error(iscsi, "Trying to send command while "
186 "not logged in.");
187 return -1;
188 }
189
190 /* We got an actual buffer from the application. Convert it to
191 * a data-out iovector.
192 */
193 if (d != NULL && d->data != NULL) {
194 struct scsi_iovec *iov;
195
196 iov = scsi_malloc(task, sizeof(struct scsi_iovec));
197 if (iov == NULL) {
198 return -1;
199 }
200 iov->iov_base = d->data;
201 iov->iov_len = d->size;
202 scsi_task_set_iov_out(task, iov, 1);
203 }
204
205 pdu = iscsi_allocate_pdu(iscsi,
206 ISCSI_PDU_SCSI_REQUEST,
207 ISCSI_PDU_SCSI_RESPONSE,
208 iscsi_itt_post_increment(iscsi),
209 0);
210 if (pdu == NULL) {
211 iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate "
212 "scsi pdu.");
213 return -1;
214 }
215
216 pdu->scsi_cbdata.task = task;
217 pdu->scsi_cbdata.callback = cb;
218 pdu->scsi_cbdata.private_data = private_data;
219
220 pdu->payload_offset = 0;
221 pdu->payload_len = 0;
222
223 scsi_set_task_private_ptr(task, &pdu->scsi_cbdata);
224
225 /* flags */
226 flags = ISCSI_PDU_SCSI_FINAL|ISCSI_PDU_SCSI_ATTR_SIMPLE;
227 switch (task->xfer_dir) {
228 case SCSI_XFER_NONE:
229 break;
230 case SCSI_XFER_READ:
231 flags |= ISCSI_PDU_SCSI_READ;
232 break;
233 case SCSI_XFER_WRITE:
234 flags |= ISCSI_PDU_SCSI_WRITE;
235
236 /* If we can send immediate data, send as much as we can */
237 if (iscsi->use_immediate_data == ISCSI_IMMEDIATE_DATA_YES) {
238 uint32_t len = task->expxferlen;
239
240 len = MIN(len, iscsi->first_burst_length);
241 len = MIN(len, iscsi->target_max_recv_data_segment_length);
242
243 pdu->payload_offset = 0;
244 pdu->payload_len = len;
245
246 /* update data segment length */
247 scsi_set_uint32(&pdu->outdata.data[4], pdu->payload_len);
248 }
249 /* We have (more) data to send and we are allowed to send
250 * it as unsolicited data-out segments.
251 * Drop the F-flag from the pdu and start sending a train
252 * of data-out further below.
253 */
254 if (iscsi->use_initial_r2t == ISCSI_INITIAL_R2T_NO
255 && pdu->payload_len < (uint32_t)task->expxferlen
256 && pdu->payload_len < iscsi->first_burst_length) {
257 /* We have more data to send, and we are allowed to send
258 * unsolicited data, so don't flag this PDU as final.
259 */
260 flags &= ~ISCSI_PDU_SCSI_FINAL;
261 }
262 break;
263 }
264 iscsi_pdu_set_pduflags(pdu, flags);
265
266 /* lun */
267 iscsi_pdu_set_lun(pdu, lun);
268 pdu->lun = lun;
269
270 /* expxferlen */
271 iscsi_pdu_set_expxferlen(pdu, task->expxferlen);
272
273 /* cmdsn */
274 iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn++);
275
276 /* cdb */
277 iscsi_pdu_set_cdb(pdu, task);
278
279 pdu->callback = iscsi_scsi_response_cb;
280 pdu->private_data = &pdu->scsi_cbdata;
281
282 if (iscsi_queue_pdu(iscsi, pdu) != 0) {
283 iscsi_set_error(iscsi, "Out-of-memory: failed to queue iscsi "
284 "scsi pdu.");
285 iscsi->drv->free_pdu(iscsi, pdu);
286 return -1;
287 }
288
289 /* The F flag is not set. This means we haven't sent all the unsolicited
290 * data yet. Sent as much as we are allowed as a train of DATA-OUT PDUs.
291 * We might already have sent some data as immediate data, which we must
292 * subtract from first_burst_length.
293 */
294 if (!(flags & ISCSI_PDU_SCSI_FINAL)) {
295 iscsi_send_unsolicited_data_out(iscsi, pdu);
296 }
297
298 /* remember cmdsn and itt so we can use task management */
299 task->cmdsn = pdu->cmdsn;
300 task->itt = pdu->itt;
301 task->lun = lun;
302
303 return 0;
304 }
305
306 /* Parse a sense key specific sense data descriptor */
parse_sense_spec(struct scsi_sense * sense,const uint8_t inf[3])307 static void parse_sense_spec(struct scsi_sense *sense, const uint8_t inf[3])
308 {
309 if (!(inf[0] & 0x80)) /* SKSV */
310 return;
311
312 sense->sense_specific = 1;
313 sense->ill_param_in_cdb = !!(inf[0] & 0x40); /* C/D flag */
314 if (inf[0] & 8) { /* BPV */
315 sense->bit_pointer_valid = 1;
316 sense->bit_pointer = inf[0] & 7;
317 }
318 sense->field_pointer = scsi_get_uint16(&inf[1]);
319 }
320
321 /* Parse descriptor format sense data */
parse_sense_descriptors(struct scsi_sense * sense,const uint8_t * sb,unsigned sb_len)322 static void parse_sense_descriptors(struct scsi_sense *sense, const uint8_t *sb,
323 unsigned sb_len)
324 {
325 const unsigned char *p, *const end = sb + sb_len;
326
327 for (p = sb; p < end; p += p[1]) {
328 if (p[1] < 4) /* length */
329 break;
330 if (!(p[2] & 0x80)) /* VALID bit */
331 break;
332 switch (p[0]) {
333 case 2:
334 /* Sense key specific sense data descriptor */
335 parse_sense_spec(sense, p + 4);
336 break;
337 }
338 }
339 }
340
scsi_parse_sense_data(struct scsi_sense * sense,const uint8_t * sb)341 void scsi_parse_sense_data(struct scsi_sense *sense, const uint8_t *sb)
342 {
343 sense->error_type = sb[0] & 0x7f;
344 switch (sense->error_type) {
345 case 0x70:
346 case 0x71:
347 /* Fixed format */
348 sense->key = sb[2] & 0x0f;
349 sense->ascq = scsi_get_uint16(&sb[12]);
350 parse_sense_spec(sense, sb + 15);
351 break;
352 case 0x72:
353 case 0x73:
354 /* Descriptor format */
355 sense->key = sb[1] & 0x0f;
356 sense->ascq = scsi_get_uint16(&sb[2]);
357 parse_sense_descriptors(sense, sb + 8, sb[7]);
358 break;
359 }
360 }
361
362 int
iscsi_process_scsi_reply(struct iscsi_context * iscsi,struct iscsi_pdu * pdu,struct iscsi_in_pdu * in)363 iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
364 struct iscsi_in_pdu *in)
365 {
366 uint8_t flags, response, status;
367 struct iscsi_scsi_cbdata *scsi_cbdata = &pdu->scsi_cbdata;
368 struct scsi_task *task = scsi_cbdata->task;
369
370 flags = in->hdr[1];
371 if ((flags&ISCSI_PDU_DATA_FINAL) == 0) {
372 iscsi_set_error(iscsi, "scsi response pdu but Final bit is "
373 "not set: 0x%02x.", flags);
374 if (pdu->callback) {
375 pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
376 pdu->private_data);
377 }
378 return -1;
379 }
380 if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) {
381 iscsi_set_error(iscsi, "scsi response asked for ACK "
382 "0x%02x.", flags);
383 if (pdu->callback) {
384 pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
385 pdu->private_data);
386 }
387 return -1;
388 }
389
390 response = in->hdr[2];
391
392 task->residual_status = SCSI_RESIDUAL_NO_RESIDUAL;
393 task->residual = 0;
394
395 if (flags & (ISCSI_PDU_DATA_RESIDUAL_OVERFLOW|
396 ISCSI_PDU_DATA_RESIDUAL_UNDERFLOW)) {
397 if (response != 0) {
398 iscsi_set_error(iscsi, "protocol error: flags %#02x;"
399 " response %#02x.", flags, response);
400 if (pdu->callback) {
401 pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
402 pdu->private_data);
403 }
404 return -1;
405 }
406 task->residual = scsi_get_uint32(&in->hdr[44]);
407 if (flags & ISCSI_PDU_DATA_RESIDUAL_UNDERFLOW) {
408 task->residual_status = SCSI_RESIDUAL_UNDERFLOW;
409 } else {
410 task->residual_status = SCSI_RESIDUAL_OVERFLOW;
411 }
412 }
413
414 status = in->hdr[3];
415
416 switch (status) {
417 case SCSI_STATUS_GOOD:
418 case SCSI_STATUS_CONDITION_MET:
419 task->datain.data = pdu->indata.data;
420 task->datain.size = pdu->indata.size;
421
422 /* the pdu->datain.data was malloc'ed by iscsi_malloc,
423 as long as we have no struct iscsi_task we cannot track
424 the free'ing of this buffer which is currently
425 done in scsi_free_scsi_task() */
426 if (pdu->indata.data != NULL) iscsi->frees++;
427
428 pdu->indata.data = NULL;
429 pdu->indata.size = 0;
430
431 if (pdu->callback) {
432 pdu->callback(iscsi, SCSI_STATUS_GOOD, task,
433 pdu->private_data);
434 }
435 break;
436 case SCSI_STATUS_CHECK_CONDITION:
437 task->datain.size = in->data_pos;
438 task->datain.data = malloc(task->datain.size);
439 if (task->datain.data == NULL) {
440 iscsi_set_error(iscsi, "failed to allocate blob for "
441 "sense data");
442 break;
443 }
444 memcpy(task->datain.data, in->data, task->datain.size);
445
446 scsi_parse_sense_data(&task->sense, &task->datain.data[2]);
447 iscsi_set_error(iscsi, "SENSE KEY:%s(%d) ASCQ:%s(0x%04x)",
448 scsi_sense_key_str(task->sense.key),
449 task->sense.key,
450 scsi_sense_ascq_str(task->sense.ascq),
451 task->sense.ascq);
452 if (task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST) {
453 iscsi_dump_pdu_header(iscsi, pdu->outdata.data);
454 }
455 if (pdu->callback) {
456 pdu->callback(iscsi, SCSI_STATUS_CHECK_CONDITION, task,
457 pdu->private_data);
458 }
459 break;
460 case SCSI_STATUS_RESERVATION_CONFLICT:
461 iscsi_set_error(iscsi, "RESERVATION CONFLICT");
462 if (pdu->callback) {
463 pdu->callback(iscsi, SCSI_STATUS_RESERVATION_CONFLICT,
464 task, pdu->private_data);
465 }
466 break;
467 case SCSI_STATUS_TASK_SET_FULL:
468 iscsi_set_error(iscsi, "TASK_SET_FULL");
469 if (pdu->callback) {
470 pdu->callback(iscsi, SCSI_STATUS_TASK_SET_FULL,
471 task, pdu->private_data);
472 }
473 break;
474 case SCSI_STATUS_ACA_ACTIVE:
475 iscsi_set_error(iscsi, "ACA_ACTIVE");
476 if (pdu->callback) {
477 pdu->callback(iscsi, SCSI_STATUS_ACA_ACTIVE,
478 task, pdu->private_data);
479 }
480 break;
481 case SCSI_STATUS_TASK_ABORTED:
482 iscsi_set_error(iscsi, "TASK_ABORTED");
483 if (pdu->callback) {
484 pdu->callback(iscsi, SCSI_STATUS_TASK_ABORTED,
485 task, pdu->private_data);
486 }
487 break;
488 case SCSI_STATUS_BUSY:
489 iscsi_set_error(iscsi, "BUSY");
490 if (pdu->callback) {
491 pdu->callback(iscsi, SCSI_STATUS_BUSY,
492 task, pdu->private_data);
493 }
494 break;
495 default:
496 iscsi_set_error(iscsi, "Unknown SCSI status :%d.", status);
497 if (pdu->callback) {
498 pdu->callback(iscsi, SCSI_STATUS_ERROR,
499 task, pdu->private_data);
500 }
501 return -1;
502 }
503
504 return 0;
505 }
506
507 int
iscsi_process_scsi_data_in(struct iscsi_context * iscsi,struct iscsi_pdu * pdu,struct iscsi_in_pdu * in,int * is_finished)508 iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
509 struct iscsi_in_pdu *in, int *is_finished)
510 {
511 uint32_t flags, status;
512 struct iscsi_scsi_cbdata *scsi_cbdata = &pdu->scsi_cbdata;
513 struct scsi_task *task = scsi_cbdata->task;
514 int dsl;
515
516 flags = in->hdr[1];
517 if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) {
518 iscsi_set_error(iscsi, "scsi response asked for ACK "
519 "0x%02x.", flags);
520 if (pdu->callback) {
521 pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
522 pdu->private_data);
523 }
524 return -1;
525 }
526 dsl = scsi_get_uint32(&in->hdr[4]) & 0x00ffffff;
527
528 /* Don't add to reassembly buffer if we already have a user buffer */
529 if (task->iovector_in.iov == NULL) {
530 if (iscsi_add_data(iscsi, &pdu->indata, in->data, dsl, 0) != 0) {
531 iscsi_set_error(iscsi, "Out-of-memory: failed to add data "
532 "to pdu in buffer.");
533 return -1;
534 }
535 }
536
537 if ((flags&ISCSI_PDU_DATA_FINAL) == 0) {
538 *is_finished = 0;
539 }
540 if ((flags&ISCSI_PDU_DATA_CONTAINS_STATUS) == 0) {
541 *is_finished = 0;
542 }
543
544 if (*is_finished == 0) {
545 return 0;
546 }
547
548 task->residual_status = SCSI_RESIDUAL_NO_RESIDUAL;
549 task->residual = 0;
550
551 /*
552 * These flags should only be set if the S flag is also set
553 */
554 if (flags & (ISCSI_PDU_DATA_RESIDUAL_OVERFLOW|ISCSI_PDU_DATA_RESIDUAL_UNDERFLOW)) {
555 task->residual = scsi_get_uint32(&in->hdr[44]);
556 if (flags & ISCSI_PDU_DATA_RESIDUAL_UNDERFLOW) {
557 task->residual_status = SCSI_RESIDUAL_UNDERFLOW;
558 } else {
559 task->residual_status = SCSI_RESIDUAL_OVERFLOW;
560 }
561 }
562
563
564 /* this was the final data-in packet in the sequence and it has
565 * the s-bit set, so invoke the callback.
566 */
567 status = in->hdr[3];
568 task->datain.data = pdu->indata.data;
569 task->datain.size = pdu->indata.size;
570
571 /* the pdu->indata.data was malloc'ed by iscsi_malloc,
572 as long as we have no struct iscsi_task we cannot track
573 the free'ing of this buffer which is currently
574 done in scsi_free_scsi_task() */
575 if (pdu->indata.data != NULL) iscsi->frees++;
576
577 pdu->indata.data = NULL;
578 pdu->indata.size = 0;
579
580 if (pdu->callback) {
581 pdu->callback(iscsi, status, task, pdu->private_data);
582 }
583
584 return 0;
585 }
586
587 int
iscsi_process_r2t(struct iscsi_context * iscsi,struct iscsi_pdu * pdu,struct iscsi_in_pdu * in)588 iscsi_process_r2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
589 struct iscsi_in_pdu *in)
590 {
591 uint32_t ttt, offset, len;
592
593 ttt = scsi_get_uint32(&in->hdr[20]);
594 offset = scsi_get_uint32(&in->hdr[40]);
595 len = scsi_get_uint32(&in->hdr[44]);
596
597 pdu->datasn = 0;
598 iscsi_send_data_out(iscsi, pdu, ttt, offset, len);
599 return 0;
600 }
601
602 /*
603 * SCSI commands
604 */
605
606 struct scsi_task *
iscsi_testunitready_task(struct iscsi_context * iscsi,int lun,iscsi_command_cb cb,void * private_data)607 iscsi_testunitready_task(struct iscsi_context *iscsi, int lun,
608 iscsi_command_cb cb, void *private_data)
609 {
610 struct scsi_task *task;
611
612 task = scsi_cdb_testunitready();
613 if (task == NULL) {
614 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
615 "testunitready cdb.");
616 return NULL;
617 }
618 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
619 NULL, private_data) != 0) {
620 scsi_free_scsi_task(task);
621 return NULL;
622 }
623
624 return task;
625 }
626
627 struct scsi_task *
iscsi_reportluns_task(struct iscsi_context * iscsi,int report_type,int alloc_len,iscsi_command_cb cb,void * private_data)628 iscsi_reportluns_task(struct iscsi_context *iscsi, int report_type,
629 int alloc_len, iscsi_command_cb cb, void *private_data)
630 {
631 struct scsi_task *task;
632
633 if (alloc_len < 16) {
634 iscsi_set_error(iscsi, "Minimum allowed alloc len for "
635 "reportluns is 16. You specified %d.",
636 alloc_len);
637 return NULL;
638 }
639
640 task = scsi_reportluns_cdb(report_type, alloc_len);
641 if (task == NULL) {
642 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
643 "reportluns cdb.");
644 return NULL;
645 }
646 /* report luns are always sent to lun 0 */
647 if (iscsi_scsi_command_async(iscsi, 0, task, cb,
648 NULL, private_data) != 0) {
649 scsi_free_scsi_task(task);
650 return NULL;
651 }
652
653 return task;
654 }
655
656 struct scsi_task *
iscsi_inquiry_task(struct iscsi_context * iscsi,int lun,int evpd,int page_code,int maxsize,iscsi_command_cb cb,void * private_data)657 iscsi_inquiry_task(struct iscsi_context *iscsi, int lun, int evpd,
658 int page_code, int maxsize,
659 iscsi_command_cb cb, void *private_data)
660 {
661 struct scsi_task *task;
662
663 task = scsi_cdb_inquiry(evpd, page_code, maxsize);
664 if (task == NULL) {
665 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
666 "inquiry cdb.");
667 return NULL;
668 }
669 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
670 NULL, private_data) != 0) {
671 scsi_free_scsi_task(task);
672 return NULL;
673 }
674
675 return task;
676 }
677
678 struct scsi_task *
iscsi_readcapacity10_task(struct iscsi_context * iscsi,int lun,int lba,int pmi,iscsi_command_cb cb,void * private_data)679 iscsi_readcapacity10_task(struct iscsi_context *iscsi, int lun, int lba,
680 int pmi, iscsi_command_cb cb, void *private_data)
681 {
682 struct scsi_task *task;
683
684 task = scsi_cdb_readcapacity10(lba, pmi);
685 if (task == NULL) {
686 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
687 "readcapacity10 cdb.");
688 return NULL;
689 }
690 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
691 NULL, private_data) != 0) {
692 scsi_free_scsi_task(task);
693 return NULL;
694 }
695
696 return task;
697 }
698
699 struct scsi_task *
iscsi_readcapacity16_task(struct iscsi_context * iscsi,int lun,iscsi_command_cb cb,void * private_data)700 iscsi_readcapacity16_task(struct iscsi_context *iscsi, int lun,
701 iscsi_command_cb cb, void *private_data)
702 {
703 struct scsi_task *task;
704
705 task = scsi_cdb_readcapacity16();
706 if (task == NULL) {
707 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
708 "readcapacity16 cdb.");
709 return NULL;
710 }
711 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
712 NULL, private_data) != 0) {
713 scsi_free_scsi_task(task);
714 return NULL;
715 }
716
717 return task;
718 }
719
720 struct scsi_task *
iscsi_readdefectdata10_task(struct iscsi_context * iscsi,int lun,int req_plist,int req_glist,int defect_list_format,uint16_t alloc_len,iscsi_command_cb cb,void * private_data)721 iscsi_readdefectdata10_task(struct iscsi_context *iscsi, int lun,
722 int req_plist, int req_glist,
723 int defect_list_format, uint16_t alloc_len,
724 iscsi_command_cb cb, void *private_data)
725 {
726 struct scsi_task *task;
727
728 task = scsi_cdb_readdefectdata10(req_plist, req_glist,
729 defect_list_format, alloc_len);
730 if (task == NULL) {
731 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
732 "readdefectdata10 cdb.");
733 return NULL;
734 }
735 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
736 NULL, private_data) != 0) {
737 scsi_free_scsi_task(task);
738 return NULL;
739 }
740
741 return task;
742 }
743
744 struct scsi_task *
iscsi_readdefectdata12_task(struct iscsi_context * iscsi,int lun,int req_plist,int req_glist,int defect_list_format,uint32_t address_descriptor_index,uint32_t alloc_len,iscsi_command_cb cb,void * private_data)745 iscsi_readdefectdata12_task(struct iscsi_context *iscsi, int lun,
746 int req_plist, int req_glist,
747 int defect_list_format,
748 uint32_t address_descriptor_index,
749 uint32_t alloc_len,
750 iscsi_command_cb cb, void *private_data)
751 {
752 struct scsi_task *task;
753
754 task = scsi_cdb_readdefectdata12(req_plist, req_glist,
755 defect_list_format,
756 address_descriptor_index, alloc_len);
757 if (task == NULL) {
758 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
759 "readdefectdata12 cdb.");
760 return NULL;
761 }
762 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
763 NULL, private_data) != 0) {
764 scsi_free_scsi_task(task);
765 return NULL;
766 }
767
768 return task;
769 }
770
771 struct scsi_task *
iscsi_get_lba_status_task(struct iscsi_context * iscsi,int lun,uint64_t starting_lba,uint32_t alloc_len,iscsi_command_cb cb,void * private_data)772 iscsi_get_lba_status_task(struct iscsi_context *iscsi, int lun,
773 uint64_t starting_lba, uint32_t alloc_len,
774 iscsi_command_cb cb, void *private_data)
775 {
776 struct scsi_task *task;
777
778 task = scsi_cdb_get_lba_status(starting_lba, alloc_len);
779 if (task == NULL) {
780 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
781 "get-lba-status cdb.");
782 return NULL;
783 }
784 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
785 NULL, private_data) != 0) {
786 scsi_free_scsi_task(task);
787 return NULL;
788 }
789
790 return task;
791 }
792
793 struct scsi_task *
iscsi_read6_iov_task(struct iscsi_context * iscsi,int lun,uint32_t lba,uint32_t datalen,int blocksize,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)794 iscsi_read6_iov_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
795 uint32_t datalen, int blocksize,
796 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
797 {
798 struct scsi_task *task;
799
800 if (datalen % blocksize != 0) {
801 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of "
802 "the blocksize:%d.", datalen, blocksize);
803 return NULL;
804 }
805
806 task = scsi_cdb_read6(lba, datalen, blocksize);
807 if (task == NULL) {
808 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
809 "read6 cdb.");
810 return NULL;
811 }
812
813 if (iov != NULL)
814 scsi_task_set_iov_in(task, iov, niov);
815
816 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
817 NULL, private_data) != 0) {
818 scsi_free_scsi_task(task);
819 return NULL;
820 }
821
822 return task;
823 }
824
825 struct scsi_task *
iscsi_read6_task(struct iscsi_context * iscsi,int lun,uint32_t lba,uint32_t datalen,int blocksize,iscsi_command_cb cb,void * private_data)826 iscsi_read6_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
827 uint32_t datalen, int blocksize,
828 iscsi_command_cb cb, void *private_data)
829 {
830 struct scsi_task *task;
831
832 if (datalen % blocksize != 0) {
833 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of "
834 "the blocksize:%d.", datalen, blocksize);
835 return NULL;
836 }
837
838 task = scsi_cdb_read6(lba, datalen, blocksize);
839 if (task == NULL) {
840 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
841 "read6 cdb.");
842 return NULL;
843 }
844 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
845 NULL, private_data) != 0) {
846 scsi_free_scsi_task(task);
847 return NULL;
848 }
849
850 return task;
851 }
852
853 struct scsi_task *
iscsi_read10_iov_task(struct iscsi_context * iscsi,int lun,uint32_t lba,uint32_t datalen,int blocksize,int rdprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)854 iscsi_read10_iov_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
855 uint32_t datalen, int blocksize,
856 int rdprotect, int dpo, int fua, int fua_nv, int group_number,
857 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
858 {
859 struct scsi_task *task;
860
861 if (datalen % blocksize != 0) {
862 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of "
863 "the blocksize:%d.", datalen, blocksize);
864 return NULL;
865 }
866
867 task = scsi_cdb_read10(lba, datalen, blocksize, rdprotect,
868 dpo, fua, fua_nv, group_number);
869 if (task == NULL) {
870 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
871 "read10 cdb.");
872 return NULL;
873 }
874
875 if (iov != NULL)
876 scsi_task_set_iov_in(task, iov, niov);
877
878 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
879 NULL, private_data) != 0) {
880 scsi_free_scsi_task(task);
881 return NULL;
882 }
883
884 return task;
885 }
886 struct scsi_task *
iscsi_read10_task(struct iscsi_context * iscsi,int lun,uint32_t lba,uint32_t datalen,int blocksize,int rdprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data)887 iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
888 uint32_t datalen, int blocksize,
889 int rdprotect, int dpo, int fua, int fua_nv, int group_number,
890 iscsi_command_cb cb, void *private_data)
891 {
892 struct scsi_task *task;
893
894 if (datalen % blocksize != 0) {
895 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of "
896 "the blocksize:%d.", datalen, blocksize);
897 return NULL;
898 }
899
900 task = scsi_cdb_read10(lba, datalen, blocksize, rdprotect,
901 dpo, fua, fua_nv, group_number);
902 if (task == NULL) {
903 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
904 "read10 cdb.");
905 return NULL;
906 }
907 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
908 NULL, private_data) != 0) {
909 scsi_free_scsi_task(task);
910 return NULL;
911 }
912
913 return task;
914 }
915
916 struct scsi_task *
iscsi_read12_iov_task(struct iscsi_context * iscsi,int lun,uint32_t lba,uint32_t datalen,int blocksize,int rdprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)917 iscsi_read12_iov_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
918 uint32_t datalen, int blocksize,
919 int rdprotect, int dpo, int fua, int fua_nv, int group_number,
920 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
921 {
922 struct scsi_task *task;
923
924 if (datalen % blocksize != 0) {
925 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of "
926 "the blocksize:%d.", datalen, blocksize);
927 return NULL;
928 }
929
930 task = scsi_cdb_read12(lba, datalen, blocksize, rdprotect,
931 dpo, fua, fua_nv, group_number);
932 if (task == NULL) {
933 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
934 "read12 cdb.");
935 return NULL;
936 }
937
938 if (iov != NULL)
939 scsi_task_set_iov_in(task, iov, niov);
940
941 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
942 NULL, private_data) != 0) {
943 scsi_free_scsi_task(task);
944 return NULL;
945 }
946
947 return task;
948 }
949
950 struct scsi_task *
iscsi_read12_task(struct iscsi_context * iscsi,int lun,uint32_t lba,uint32_t datalen,int blocksize,int rdprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data)951 iscsi_read12_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
952 uint32_t datalen, int blocksize,
953 int rdprotect, int dpo, int fua, int fua_nv, int group_number,
954 iscsi_command_cb cb, void *private_data)
955 {
956 struct scsi_task *task;
957
958 if (datalen % blocksize != 0) {
959 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of "
960 "the blocksize:%d.", datalen, blocksize);
961 return NULL;
962 }
963
964 task = scsi_cdb_read12(lba, datalen, blocksize, rdprotect,
965 dpo, fua, fua_nv, group_number);
966 if (task == NULL) {
967 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
968 "read12 cdb.");
969 return NULL;
970 }
971 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
972 NULL, private_data) != 0) {
973 scsi_free_scsi_task(task);
974 return NULL;
975 }
976
977 return task;
978 }
979
980 struct scsi_task *
iscsi_read16_iov_task(struct iscsi_context * iscsi,int lun,uint64_t lba,uint32_t datalen,int blocksize,int rdprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)981 iscsi_read16_iov_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
982 uint32_t datalen, int blocksize,
983 int rdprotect, int dpo, int fua, int fua_nv, int group_number,
984 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
985 {
986 struct scsi_task *task;
987
988 if (datalen % blocksize != 0) {
989 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of "
990 "the blocksize:%d.", datalen, blocksize);
991 return NULL;
992 }
993
994 task = scsi_cdb_read16(lba, datalen, blocksize, rdprotect,
995 dpo, fua, fua_nv, group_number);
996 if (task == NULL) {
997 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
998 "read16 cdb.");
999 return NULL;
1000 }
1001
1002 if (iov != NULL)
1003 scsi_task_set_iov_in(task, iov, niov);
1004
1005 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1006 NULL, private_data) != 0) {
1007 scsi_free_scsi_task(task);
1008 return NULL;
1009 }
1010
1011 return task;
1012 }
1013
1014 struct scsi_task *
iscsi_read16_task(struct iscsi_context * iscsi,int lun,uint64_t lba,uint32_t datalen,int blocksize,int rdprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data)1015 iscsi_read16_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1016 uint32_t datalen, int blocksize,
1017 int rdprotect, int dpo, int fua, int fua_nv, int group_number,
1018 iscsi_command_cb cb, void *private_data)
1019 {
1020 struct scsi_task *task;
1021
1022 if (datalen % blocksize != 0) {
1023 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of "
1024 "the blocksize:%d.", datalen, blocksize);
1025 return NULL;
1026 }
1027
1028 task = scsi_cdb_read16(lba, datalen, blocksize, rdprotect,
1029 dpo, fua, fua_nv, group_number);
1030 if (task == NULL) {
1031 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1032 "read16 cdb.");
1033 return NULL;
1034 }
1035 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1036 NULL, private_data) != 0) {
1037 scsi_free_scsi_task(task);
1038 return NULL;
1039 }
1040
1041 return task;
1042 }
1043
1044 struct scsi_task *
iscsi_write10_task(struct iscsi_context * iscsi,int lun,uint32_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data)1045 iscsi_write10_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
1046 unsigned char *data, uint32_t datalen, int blocksize,
1047 int wrprotect, int dpo, int fua, int fua_nv, int group_number,
1048 iscsi_command_cb cb, void *private_data)
1049 {
1050 struct scsi_task *task;
1051 struct iscsi_data d;
1052
1053 if (datalen % blocksize != 0) {
1054 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1055 "blocksize:%d.", datalen, blocksize);
1056 return NULL;
1057 }
1058
1059 task = scsi_cdb_write10(lba, datalen, blocksize, wrprotect,
1060 dpo, fua, fua_nv, group_number);
1061 if (task == NULL) {
1062 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1063 "write10 cdb.");
1064 return NULL;
1065 }
1066 d.data = data;
1067 d.size = datalen;
1068
1069 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1070 &d, private_data) != 0) {
1071 scsi_free_scsi_task(task);
1072 return NULL;
1073 }
1074
1075 return task;
1076 }
1077
1078 struct scsi_task *
iscsi_write10_iov_task(struct iscsi_context * iscsi,int lun,uint32_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1079 iscsi_write10_iov_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
1080 unsigned char *data, uint32_t datalen, int blocksize,
1081 int wrprotect, int dpo, int fua, int fua_nv, int group_number,
1082 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
1083 {
1084 struct scsi_task *task;
1085 struct iscsi_data d;
1086
1087 if (datalen % blocksize != 0) {
1088 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1089 "blocksize:%d.", datalen, blocksize);
1090 return NULL;
1091 }
1092
1093 task = scsi_cdb_write10(lba, datalen, blocksize, wrprotect,
1094 dpo, fua, fua_nv, group_number);
1095 if (task == NULL) {
1096 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1097 "write10 cdb.");
1098 return NULL;
1099 }
1100 d.data = data;
1101 d.size = datalen;
1102
1103 if (iov != NULL)
1104 scsi_task_set_iov_out(task, iov, niov);
1105
1106
1107 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1108 &d, private_data) != 0) {
1109 scsi_free_scsi_task(task);
1110 return NULL;
1111 }
1112
1113 return task;
1114 }
1115
1116 struct scsi_task *
iscsi_write12_task(struct iscsi_context * iscsi,int lun,uint32_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data)1117 iscsi_write12_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
1118 unsigned char *data, uint32_t datalen, int blocksize,
1119 int wrprotect, int dpo, int fua, int fua_nv, int group_number,
1120 iscsi_command_cb cb, void *private_data)
1121 {
1122 struct scsi_task *task;
1123 struct iscsi_data d;
1124
1125 if (datalen % blocksize != 0) {
1126 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1127 "blocksize:%d.", datalen, blocksize);
1128 return NULL;
1129 }
1130
1131 task = scsi_cdb_write12(lba, datalen, blocksize, wrprotect,
1132 dpo, fua, fua_nv, group_number);
1133 if (task == NULL) {
1134 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1135 "write12 cdb.");
1136 return NULL;
1137 }
1138 d.data = data;
1139 d.size = datalen;
1140
1141 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1142 &d, private_data) != 0) {
1143 scsi_free_scsi_task(task);
1144 return NULL;
1145 }
1146
1147 return task;
1148 }
1149
1150 struct scsi_task *
iscsi_write12_iov_task(struct iscsi_context * iscsi,int lun,uint32_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1151 iscsi_write12_iov_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
1152 unsigned char *data, uint32_t datalen, int blocksize,
1153 int wrprotect, int dpo, int fua, int fua_nv, int group_number,
1154 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
1155 {
1156 struct scsi_task *task;
1157 struct iscsi_data d;
1158
1159 if (datalen % blocksize != 0) {
1160 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1161 "blocksize:%d.", datalen, blocksize);
1162 return NULL;
1163 }
1164
1165 task = scsi_cdb_write12(lba, datalen, blocksize, wrprotect,
1166 dpo, fua, fua_nv, group_number);
1167 if (task == NULL) {
1168 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1169 "write12 cdb.");
1170 return NULL;
1171 }
1172 d.data = data;
1173 d.size = datalen;
1174
1175 if (iov != NULL)
1176 scsi_task_set_iov_out(task, iov, niov);
1177
1178 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1179 &d, private_data) != 0) {
1180 scsi_free_scsi_task(task);
1181 return NULL;
1182 }
1183
1184 return task;
1185 }
1186
1187 struct scsi_task *
iscsi_write16_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data)1188 iscsi_write16_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1189 unsigned char *data, uint32_t datalen, int blocksize,
1190 int wrprotect, int dpo, int fua, int fua_nv, int group_number,
1191 iscsi_command_cb cb, void *private_data)
1192 {
1193 struct scsi_task *task;
1194 struct iscsi_data d;
1195
1196 if (datalen % blocksize != 0) {
1197 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1198 "blocksize:%d.", datalen, blocksize);
1199 return NULL;
1200 }
1201
1202 task = scsi_cdb_write16(lba, datalen, blocksize, wrprotect,
1203 dpo, fua, fua_nv, group_number);
1204 if (task == NULL) {
1205 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1206 "write16 cdb.");
1207 return NULL;
1208 }
1209 d.data = data;
1210 d.size = datalen;
1211
1212 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1213 &d, private_data) != 0) {
1214 scsi_free_scsi_task(task);
1215 return NULL;
1216 }
1217
1218 return task;
1219 }
1220
1221 struct scsi_task *
iscsi_write16_iov_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1222 iscsi_write16_iov_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1223 unsigned char *data, uint32_t datalen, int blocksize,
1224 int wrprotect, int dpo, int fua, int fua_nv, int group_number,
1225 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
1226 {
1227 struct scsi_task *task;
1228 struct iscsi_data d;
1229
1230 if (datalen % blocksize != 0) {
1231 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1232 "blocksize:%d.", datalen, blocksize);
1233 return NULL;
1234 }
1235
1236 task = scsi_cdb_write16(lba, datalen, blocksize, wrprotect,
1237 dpo, fua, fua_nv, group_number);
1238 if (task == NULL) {
1239 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1240 "write16 cdb.");
1241 return NULL;
1242 }
1243 d.data = data;
1244 d.size = datalen;
1245
1246 if (iov != NULL)
1247 scsi_task_set_iov_out(task, iov, niov);
1248
1249 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1250 &d, private_data) != 0) {
1251 scsi_free_scsi_task(task);
1252 return NULL;
1253 }
1254
1255 return task;
1256 }
1257
1258 struct scsi_task *
iscsi_writeatomic16_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int group_number,iscsi_command_cb cb,void * private_data)1259 iscsi_writeatomic16_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1260 unsigned char *data, uint32_t datalen, int blocksize,
1261 int wrprotect, int dpo, int fua, int group_number,
1262 iscsi_command_cb cb, void *private_data)
1263 {
1264 struct scsi_task *task;
1265 struct iscsi_data d;
1266
1267 if (datalen % blocksize != 0) {
1268 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1269 "blocksize:%d.", datalen, blocksize);
1270 return NULL;
1271 }
1272
1273 task = scsi_cdb_writeatomic16(lba, datalen, blocksize, wrprotect,
1274 dpo, fua, group_number);
1275 if (task == NULL) {
1276 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1277 "writeAtomic16 cdb.");
1278 return NULL;
1279 }
1280 d.data = data;
1281 d.size = datalen;
1282
1283 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1284 &d, private_data) != 0) {
1285 scsi_free_scsi_task(task);
1286 return NULL;
1287 }
1288
1289 return task;
1290 }
1291
1292 struct scsi_task *
iscsi_writeatomic16_iov_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1293 iscsi_writeatomic16_iov_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1294 unsigned char *data, uint32_t datalen, int blocksize,
1295 int wrprotect, int dpo, int fua, int group_number,
1296 iscsi_command_cb cb, void *private_data,
1297 struct scsi_iovec *iov, int niov)
1298 {
1299 struct scsi_task *task;
1300 struct iscsi_data d;
1301
1302 if (datalen % blocksize != 0) {
1303 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1304 "blocksize:%d.", datalen, blocksize);
1305 return NULL;
1306 }
1307
1308 task = scsi_cdb_writeatomic16(lba, datalen, blocksize, wrprotect,
1309 dpo, fua, group_number);
1310 if (task == NULL) {
1311 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1312 "writeAtomic16 cdb.");
1313 return NULL;
1314 }
1315 d.data = data;
1316 d.size = datalen;
1317
1318 if (iov != NULL)
1319 scsi_task_set_iov_out(task, iov, niov);
1320
1321 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1322 &d, private_data) != 0) {
1323 scsi_free_scsi_task(task);
1324 return NULL;
1325 }
1326
1327 return task;
1328 }
1329
1330 struct scsi_task *
iscsi_orwrite_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data)1331 iscsi_orwrite_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1332 unsigned char *data, uint32_t datalen, int blocksize,
1333 int wrprotect, int dpo, int fua, int fua_nv, int group_number,
1334 iscsi_command_cb cb, void *private_data)
1335 {
1336 struct scsi_task *task;
1337 struct iscsi_data d;
1338
1339 if (datalen % blocksize != 0) {
1340 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1341 "blocksize:%d.", datalen, blocksize);
1342 return NULL;
1343 }
1344
1345 task = scsi_cdb_orwrite(lba, datalen, blocksize, wrprotect,
1346 dpo, fua, fua_nv, group_number);
1347 if (task == NULL) {
1348 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1349 "orwrite cdb.");
1350 return NULL;
1351 }
1352 d.data = data;
1353 d.size = datalen;
1354
1355 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1356 &d, private_data) != 0) {
1357 scsi_free_scsi_task(task);
1358 return NULL;
1359 }
1360
1361 return task;
1362 }
1363
1364 struct scsi_task *
iscsi_orwrite_iov_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1365 iscsi_orwrite_iov_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1366 unsigned char *data, uint32_t datalen, int blocksize,
1367 int wrprotect, int dpo, int fua, int fua_nv, int group_number,
1368 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
1369 {
1370 struct scsi_task *task;
1371 struct iscsi_data d;
1372
1373 if (datalen % blocksize != 0) {
1374 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1375 "blocksize:%d.", datalen, blocksize);
1376 return NULL;
1377 }
1378
1379 task = scsi_cdb_orwrite(lba, datalen, blocksize, wrprotect,
1380 dpo, fua, fua_nv, group_number);
1381 if (task == NULL) {
1382 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1383 "orwrite cdb.");
1384 return NULL;
1385 }
1386 d.data = data;
1387 d.size = datalen;
1388
1389 if (iov != NULL)
1390 scsi_task_set_iov_out(task, iov, niov);
1391
1392 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1393 &d, private_data) != 0) {
1394 scsi_free_scsi_task(task);
1395 return NULL;
1396 }
1397
1398 return task;
1399 }
1400
1401 struct scsi_task *
iscsi_compareandwrite_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data)1402 iscsi_compareandwrite_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1403 unsigned char *data, uint32_t datalen, int blocksize,
1404 int wrprotect, int dpo, int fua, int fua_nv, int group_number,
1405 iscsi_command_cb cb, void *private_data)
1406 {
1407 struct scsi_task *task;
1408 struct iscsi_data d;
1409
1410 if (datalen % (blocksize * 2) != 0) {
1411 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1412 "blocksize * 2:%d.", datalen, blocksize * 2);
1413 return NULL;
1414 }
1415
1416 task = scsi_cdb_compareandwrite(lba, datalen, blocksize, wrprotect,
1417 dpo, fua, fua_nv, group_number);
1418 if (task == NULL) {
1419 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1420 "compareandwrite cdb.");
1421 return NULL;
1422 }
1423 d.data = data;
1424 d.size = datalen;
1425
1426 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1427 &d, private_data) != 0) {
1428 scsi_free_scsi_task(task);
1429 return NULL;
1430 }
1431
1432 return task;
1433 }
1434
1435 struct scsi_task *
iscsi_compareandwrite_iov_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int fua,int fua_nv,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1436 iscsi_compareandwrite_iov_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1437 unsigned char *data, uint32_t datalen, int blocksize,
1438 int wrprotect, int dpo, int fua, int fua_nv, int group_number,
1439 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
1440 {
1441 struct scsi_task *task;
1442 struct iscsi_data d;
1443
1444 if (datalen % (blocksize * 2) != 0) {
1445 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1446 "blocksize * 2:%d.", datalen, blocksize * 2);
1447 return NULL;
1448 }
1449
1450 task = scsi_cdb_compareandwrite(lba, datalen, blocksize, wrprotect,
1451 dpo, fua, fua_nv, group_number);
1452 if (task == NULL) {
1453 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1454 "compareandwrite cdb.");
1455 return NULL;
1456 }
1457 d.data = data;
1458 d.size = datalen;
1459
1460 if (iov != NULL)
1461 scsi_task_set_iov_out(task, iov, niov);
1462
1463 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1464 &d, private_data) != 0) {
1465 scsi_free_scsi_task(task);
1466 return NULL;
1467 }
1468
1469 return task;
1470 }
1471
1472 struct scsi_task *
iscsi_writeverify10_task(struct iscsi_context * iscsi,int lun,uint32_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int bytchk,int group_number,iscsi_command_cb cb,void * private_data)1473 iscsi_writeverify10_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
1474 unsigned char *data, uint32_t datalen, int blocksize,
1475 int wrprotect, int dpo, int bytchk, int group_number,
1476 iscsi_command_cb cb, void *private_data)
1477 {
1478 struct scsi_task *task;
1479 struct iscsi_data d;
1480
1481 if (datalen % blocksize != 0) {
1482 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1483 "blocksize:%d.", datalen, blocksize);
1484 return NULL;
1485 }
1486
1487 task = scsi_cdb_writeverify10(lba, datalen, blocksize, wrprotect,
1488 dpo, bytchk, group_number);
1489 if (task == NULL) {
1490 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1491 "writeverify10 cdb.");
1492 return NULL;
1493 }
1494 d.data = data;
1495 d.size = datalen;
1496
1497 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1498 &d, private_data) != 0) {
1499 scsi_free_scsi_task(task);
1500 return NULL;
1501 }
1502
1503 return task;
1504 }
1505
1506 struct scsi_task *
iscsi_writeverify10_iov_task(struct iscsi_context * iscsi,int lun,uint32_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int bytchk,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1507 iscsi_writeverify10_iov_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
1508 unsigned char *data, uint32_t datalen, int blocksize,
1509 int wrprotect, int dpo, int bytchk, int group_number,
1510 iscsi_command_cb cb, void *private_data,
1511 struct scsi_iovec *iov, int niov)
1512 {
1513 struct scsi_task *task;
1514 struct iscsi_data d;
1515
1516 if (datalen % blocksize != 0) {
1517 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1518 "blocksize:%d.", datalen, blocksize);
1519 return NULL;
1520 }
1521
1522 task = scsi_cdb_writeverify10(lba, datalen, blocksize, wrprotect,
1523 dpo, bytchk, group_number);
1524 if (task == NULL) {
1525 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1526 "writeverify10 cdb.");
1527 return NULL;
1528 }
1529 d.data = data;
1530 d.size = datalen;
1531
1532 if (iov != NULL)
1533 scsi_task_set_iov_out(task, iov, niov);
1534
1535 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1536 &d, private_data) != 0) {
1537 scsi_free_scsi_task(task);
1538 return NULL;
1539 }
1540
1541 return task;
1542 }
1543
1544 struct scsi_task *
iscsi_writeverify12_task(struct iscsi_context * iscsi,int lun,uint32_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int bytchk,int group_number,iscsi_command_cb cb,void * private_data)1545 iscsi_writeverify12_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
1546 unsigned char *data, uint32_t datalen, int blocksize,
1547 int wrprotect, int dpo, int bytchk, int group_number,
1548 iscsi_command_cb cb, void *private_data)
1549 {
1550 struct scsi_task *task;
1551 struct iscsi_data d;
1552
1553 if (datalen % blocksize != 0) {
1554 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1555 "blocksize:%d.", datalen, blocksize);
1556 return NULL;
1557 }
1558
1559 task = scsi_cdb_writeverify12(lba, datalen, blocksize, wrprotect,
1560 dpo, bytchk, group_number);
1561 if (task == NULL) {
1562 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1563 "writeverify12 cdb.");
1564 return NULL;
1565 }
1566 d.data = data;
1567 d.size = datalen;
1568
1569 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1570 &d, private_data) != 0) {
1571 scsi_free_scsi_task(task);
1572 return NULL;
1573 }
1574
1575 return task;
1576 }
1577
1578 struct scsi_task *
iscsi_writeverify12_iov_task(struct iscsi_context * iscsi,int lun,uint32_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int bytchk,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1579 iscsi_writeverify12_iov_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
1580 unsigned char *data, uint32_t datalen, int blocksize,
1581 int wrprotect, int dpo, int bytchk, int group_number,
1582 iscsi_command_cb cb, void *private_data,
1583 struct scsi_iovec *iov, int niov)
1584 {
1585 struct scsi_task *task;
1586 struct iscsi_data d;
1587
1588 if (datalen % blocksize != 0) {
1589 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1590 "blocksize:%d.", datalen, blocksize);
1591 return NULL;
1592 }
1593
1594 task = scsi_cdb_writeverify12(lba, datalen, blocksize, wrprotect,
1595 dpo, bytchk, group_number);
1596 if (task == NULL) {
1597 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1598 "writeverify12 cdb.");
1599 return NULL;
1600 }
1601 d.data = data;
1602 d.size = datalen;
1603
1604 if (iov != NULL)
1605 scsi_task_set_iov_out(task, iov, niov);
1606
1607 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1608 &d, private_data) != 0) {
1609 scsi_free_scsi_task(task);
1610 return NULL;
1611 }
1612
1613 return task;
1614 }
1615
1616 struct scsi_task *
iscsi_writeverify16_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int bytchk,int group_number,iscsi_command_cb cb,void * private_data)1617 iscsi_writeverify16_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1618 unsigned char *data, uint32_t datalen, int blocksize,
1619 int wrprotect, int dpo, int bytchk, int group_number,
1620 iscsi_command_cb cb, void *private_data)
1621 {
1622 struct scsi_task *task;
1623 struct iscsi_data d;
1624
1625 if (datalen % blocksize != 0) {
1626 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1627 "blocksize:%d.", datalen, blocksize);
1628 return NULL;
1629 }
1630
1631 task = scsi_cdb_writeverify16(lba, datalen, blocksize, wrprotect,
1632 dpo, bytchk, group_number);
1633 if (task == NULL) {
1634 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1635 "writeverify16 cdb.");
1636 return NULL;
1637 }
1638 d.data = data;
1639 d.size = datalen;
1640
1641 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1642 &d, private_data) != 0) {
1643 scsi_free_scsi_task(task);
1644 return NULL;
1645 }
1646
1647 return task;
1648 }
1649
1650 struct scsi_task *
iscsi_writeverify16_iov_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,int blocksize,int wrprotect,int dpo,int bytchk,int group_number,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1651 iscsi_writeverify16_iov_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
1652 unsigned char *data, uint32_t datalen, int blocksize,
1653 int wrprotect, int dpo, int bytchk, int group_number,
1654 iscsi_command_cb cb, void *private_data,
1655 struct scsi_iovec *iov, int niov)
1656 {
1657 struct scsi_task *task;
1658 struct iscsi_data d;
1659
1660 if (datalen % blocksize != 0) {
1661 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1662 "blocksize:%d.", datalen, blocksize);
1663 return NULL;
1664 }
1665
1666 task = scsi_cdb_writeverify16(lba, datalen, blocksize, wrprotect,
1667 dpo, bytchk, group_number);
1668 if (task == NULL) {
1669 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1670 "writeverify16 cdb.");
1671 return NULL;
1672 }
1673 d.data = data;
1674 d.size = datalen;
1675
1676 if (iov != NULL)
1677 scsi_task_set_iov_out(task, iov, niov);
1678
1679 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1680 &d, private_data) != 0) {
1681 scsi_free_scsi_task(task);
1682 return NULL;
1683 }
1684
1685 return task;
1686 }
1687
1688 struct scsi_task *
iscsi_verify10_task(struct iscsi_context * iscsi,int lun,unsigned char * data,uint32_t datalen,uint32_t lba,int vprotect,int dpo,int bytchk,int blocksize,iscsi_command_cb cb,void * private_data)1689 iscsi_verify10_task(struct iscsi_context *iscsi, int lun, unsigned char *data,
1690 uint32_t datalen, uint32_t lba, int vprotect, int dpo, int bytchk, int blocksize,
1691 iscsi_command_cb cb, void *private_data)
1692 {
1693 struct scsi_task *task;
1694 struct iscsi_data d;
1695
1696 if (datalen % blocksize != 0) {
1697 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1698 "blocksize:%d.", datalen, blocksize);
1699 return NULL;
1700 }
1701
1702 task = scsi_cdb_verify10(lba, datalen, vprotect, dpo, bytchk, blocksize);
1703 if (task == NULL) {
1704 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1705 "verify10 cdb.");
1706 return NULL;
1707 }
1708 d.data = data;
1709 d.size = datalen;
1710
1711 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1712 &d, private_data) != 0) {
1713 scsi_free_scsi_task(task);
1714 return NULL;
1715 }
1716
1717 return task;
1718 }
1719
1720 struct scsi_task *
iscsi_verify10_iov_task(struct iscsi_context * iscsi,int lun,unsigned char * data,uint32_t datalen,uint32_t lba,int vprotect,int dpo,int bytchk,int blocksize,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1721 iscsi_verify10_iov_task(struct iscsi_context *iscsi, int lun, unsigned char *data,
1722 uint32_t datalen, uint32_t lba, int vprotect, int dpo, int bytchk, int blocksize,
1723 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
1724 {
1725 struct scsi_task *task;
1726 struct iscsi_data d;
1727
1728 if (datalen % blocksize != 0) {
1729 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1730 "blocksize:%d.", datalen, blocksize);
1731 return NULL;
1732 }
1733
1734 task = scsi_cdb_verify10(lba, datalen, vprotect, dpo, bytchk, blocksize);
1735 if (task == NULL) {
1736 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1737 "verify10 cdb.");
1738 return NULL;
1739 }
1740 d.data = data;
1741 d.size = datalen;
1742
1743 if (iov != NULL)
1744 scsi_task_set_iov_out(task, iov, niov);
1745
1746 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1747 &d, private_data) != 0) {
1748 scsi_free_scsi_task(task);
1749 return NULL;
1750 }
1751
1752 return task;
1753 }
1754
1755 struct scsi_task *
iscsi_verify12_task(struct iscsi_context * iscsi,int lun,unsigned char * data,uint32_t datalen,uint32_t lba,int vprotect,int dpo,int bytchk,int blocksize,iscsi_command_cb cb,void * private_data)1756 iscsi_verify12_task(struct iscsi_context *iscsi, int lun, unsigned char *data,
1757 uint32_t datalen, uint32_t lba, int vprotect, int dpo, int bytchk, int blocksize,
1758 iscsi_command_cb cb, void *private_data)
1759 {
1760 struct scsi_task *task;
1761 struct iscsi_data d;
1762
1763 if (datalen % blocksize != 0) {
1764 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1765 "blocksize:%d.", datalen, blocksize);
1766 return NULL;
1767 }
1768
1769 task = scsi_cdb_verify12(lba, datalen, vprotect, dpo, bytchk, blocksize);
1770 if (task == NULL) {
1771 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1772 "verify12 cdb.");
1773 return NULL;
1774 }
1775 d.data = data;
1776 d.size = datalen;
1777
1778 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1779 &d, private_data) != 0) {
1780 scsi_free_scsi_task(task);
1781 return NULL;
1782 }
1783
1784 return task;
1785 }
1786
1787 struct scsi_task *
iscsi_verify12_iov_task(struct iscsi_context * iscsi,int lun,unsigned char * data,uint32_t datalen,uint32_t lba,int vprotect,int dpo,int bytchk,int blocksize,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1788 iscsi_verify12_iov_task(struct iscsi_context *iscsi, int lun, unsigned char *data,
1789 uint32_t datalen, uint32_t lba, int vprotect, int dpo, int bytchk, int blocksize,
1790 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
1791 {
1792 struct scsi_task *task;
1793 struct iscsi_data d;
1794
1795 if (datalen % blocksize != 0) {
1796 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1797 "blocksize:%d.", datalen, blocksize);
1798 return NULL;
1799 }
1800
1801 task = scsi_cdb_verify12(lba, datalen, vprotect, dpo, bytchk, blocksize);
1802 if (task == NULL) {
1803 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1804 "verify12 cdb.");
1805 return NULL;
1806 }
1807 d.data = data;
1808 d.size = datalen;
1809
1810 if (iov != NULL)
1811 scsi_task_set_iov_out(task, iov, niov);
1812
1813 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1814 &d, private_data) != 0) {
1815 scsi_free_scsi_task(task);
1816 return NULL;
1817 }
1818
1819 return task;
1820 }
1821
1822 struct scsi_task *
iscsi_verify16_task(struct iscsi_context * iscsi,int lun,unsigned char * data,uint32_t datalen,uint64_t lba,int vprotect,int dpo,int bytchk,int blocksize,iscsi_command_cb cb,void * private_data)1823 iscsi_verify16_task(struct iscsi_context *iscsi, int lun, unsigned char *data,
1824 uint32_t datalen, uint64_t lba, int vprotect, int dpo, int bytchk, int blocksize,
1825 iscsi_command_cb cb, void *private_data)
1826 {
1827 struct scsi_task *task;
1828 struct iscsi_data d;
1829
1830 if (datalen % blocksize != 0) {
1831 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1832 "blocksize:%d.", datalen, blocksize);
1833 return NULL;
1834 }
1835
1836 task = scsi_cdb_verify16(lba, datalen, vprotect, dpo, bytchk, blocksize);
1837 if (task == NULL) {
1838 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1839 "verify16 cdb.");
1840 return NULL;
1841 }
1842 d.data = data;
1843 d.size = datalen;
1844
1845 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1846 &d, private_data) != 0) {
1847 scsi_free_scsi_task(task);
1848 return NULL;
1849 }
1850
1851 return task;
1852 }
1853
1854 struct scsi_task *
iscsi_verify16_iov_task(struct iscsi_context * iscsi,int lun,unsigned char * data,uint32_t datalen,uint64_t lba,int vprotect,int dpo,int bytchk,int blocksize,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)1855 iscsi_verify16_iov_task(struct iscsi_context *iscsi, int lun, unsigned char *data,
1856 uint32_t datalen, uint64_t lba, int vprotect, int dpo, int bytchk, int blocksize,
1857 iscsi_command_cb cb, void *private_data, struct scsi_iovec *iov, int niov)
1858 {
1859 struct scsi_task *task;
1860 struct iscsi_data d;
1861
1862 if (datalen % blocksize != 0) {
1863 iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the "
1864 "blocksize:%d.", datalen, blocksize);
1865 return NULL;
1866 }
1867
1868 task = scsi_cdb_verify16(lba, datalen, vprotect, dpo, bytchk, blocksize);
1869 if (task == NULL) {
1870 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1871 "verify16 cdb.");
1872 return NULL;
1873 }
1874 d.data = data;
1875 d.size = datalen;
1876
1877 if (iov != NULL)
1878 scsi_task_set_iov_out(task, iov, niov);
1879
1880 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1881 &d, private_data) != 0) {
1882 scsi_free_scsi_task(task);
1883 return NULL;
1884 }
1885
1886 return task;
1887 }
1888
1889 struct scsi_task *
iscsi_modeselect6_task(struct iscsi_context * iscsi,int lun,int pf,int sp,struct scsi_mode_page * mp,iscsi_command_cb cb,void * private_data)1890 iscsi_modeselect6_task(struct iscsi_context *iscsi, int lun,
1891 int pf, int sp, struct scsi_mode_page *mp,
1892 iscsi_command_cb cb, void *private_data)
1893 {
1894 struct scsi_task *task;
1895 struct scsi_data *data;
1896 struct iscsi_data d;
1897
1898 task = scsi_cdb_modeselect6(pf, sp, 255);
1899 if (task == NULL) {
1900 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1901 "modeselect6 cdb.");
1902 return NULL;
1903 }
1904 data = scsi_modesense_dataout_marshall(task, mp, 1);
1905 if (data == NULL) {
1906 iscsi_set_error(iscsi, "Error: Failed to marshall "
1907 "modesense dataout buffer.");
1908 scsi_free_scsi_task(task);
1909 return NULL;
1910 }
1911
1912 d.data = data->data;
1913 d.size = data->size;
1914 task->cdb[4] = data->size;
1915 task->expxferlen = data->size;
1916
1917 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1918 &d, private_data) != 0) {
1919 scsi_free_scsi_task(task);
1920 return NULL;
1921 }
1922
1923 return task;
1924 }
1925
1926 struct scsi_task *
iscsi_modeselect10_task(struct iscsi_context * iscsi,int lun,int pf,int sp,struct scsi_mode_page * mp,iscsi_command_cb cb,void * private_data)1927 iscsi_modeselect10_task(struct iscsi_context *iscsi, int lun,
1928 int pf, int sp, struct scsi_mode_page *mp,
1929 iscsi_command_cb cb, void *private_data)
1930 {
1931 struct scsi_task *task;
1932 struct scsi_data *data;
1933 struct iscsi_data d;
1934
1935 task = scsi_cdb_modeselect10(pf, sp, 255);
1936 if (task == NULL) {
1937 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1938 "modeselect10 cdb.");
1939 return NULL;
1940 }
1941 data = scsi_modesense_dataout_marshall(task, mp, 0);
1942 if (data == NULL) {
1943 iscsi_set_error(iscsi, "Error: Failed to marshall "
1944 "modesense dataout buffer.");
1945 scsi_free_scsi_task(task);
1946 return NULL;
1947 }
1948
1949 d.data = data->data;
1950 d.size = data->size;
1951 task->cdb[7] = data->size >> 8;
1952 task->cdb[8] = data->size & 0xff;
1953
1954 task->expxferlen = data->size;
1955
1956 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1957 &d, private_data) != 0) {
1958 scsi_free_scsi_task(task);
1959 return NULL;
1960 }
1961
1962 return task;
1963 }
1964
1965 struct scsi_task *
iscsi_modesense6_task(struct iscsi_context * iscsi,int lun,int dbd,int pc,int page_code,int sub_page_code,unsigned char alloc_len,iscsi_command_cb cb,void * private_data)1966 iscsi_modesense6_task(struct iscsi_context *iscsi, int lun, int dbd, int pc,
1967 int page_code, int sub_page_code,
1968 unsigned char alloc_len,
1969 iscsi_command_cb cb, void *private_data)
1970 {
1971 struct scsi_task *task;
1972
1973 task = scsi_cdb_modesense6(dbd, pc, page_code, sub_page_code,
1974 alloc_len);
1975 if (task == NULL) {
1976 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
1977 "modesense6 cdb.");
1978 return NULL;
1979 }
1980 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
1981 NULL, private_data) != 0) {
1982 scsi_free_scsi_task(task);
1983 return NULL;
1984 }
1985
1986 return task;
1987 }
1988
1989 struct scsi_task *
iscsi_modesense10_task(struct iscsi_context * iscsi,int lun,int llbaa,int dbd,int pc,int page_code,int sub_page_code,unsigned char alloc_len,iscsi_command_cb cb,void * private_data)1990 iscsi_modesense10_task(struct iscsi_context *iscsi, int lun,
1991 int llbaa, int dbd, int pc,
1992 int page_code, int sub_page_code,
1993 unsigned char alloc_len,
1994 iscsi_command_cb cb, void *private_data)
1995 {
1996 struct scsi_task *task;
1997
1998 task = scsi_cdb_modesense10(llbaa, dbd, pc, page_code, sub_page_code,
1999 alloc_len);
2000 if (task == NULL) {
2001 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2002 "modesense10 cdb.");
2003 return NULL;
2004 }
2005 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2006 NULL, private_data) != 0) {
2007 scsi_free_scsi_task(task);
2008 return NULL;
2009 }
2010
2011 return task;
2012 }
2013
2014 struct scsi_task *
iscsi_startstopunit_task(struct iscsi_context * iscsi,int lun,int immed,int pcm,int pc,int no_flush,int loej,int start,iscsi_command_cb cb,void * private_data)2015 iscsi_startstopunit_task(struct iscsi_context *iscsi, int lun,
2016 int immed, int pcm, int pc,
2017 int no_flush, int loej, int start,
2018 iscsi_command_cb cb, void *private_data)
2019 {
2020 struct scsi_task *task;
2021
2022 task = scsi_cdb_startstopunit(immed, pcm, pc, no_flush,
2023 loej, start);
2024 if (task == NULL) {
2025 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2026 "startstopunit cdb.");
2027 return NULL;
2028 }
2029 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2030 NULL, private_data) != 0) {
2031 scsi_free_scsi_task(task);
2032 return NULL;
2033 }
2034
2035 return task;
2036 }
2037
2038 struct scsi_task *
iscsi_preventallow_task(struct iscsi_context * iscsi,int lun,int prevent,iscsi_command_cb cb,void * private_data)2039 iscsi_preventallow_task(struct iscsi_context *iscsi, int lun,
2040 int prevent,
2041 iscsi_command_cb cb, void *private_data)
2042 {
2043 struct scsi_task *task;
2044
2045 task = scsi_cdb_preventallow(prevent);
2046 if (task == NULL) {
2047 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2048 "PreventAllowMediumRemoval cdb.");
2049 return NULL;
2050 }
2051 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2052 NULL, private_data) != 0) {
2053 scsi_free_scsi_task(task);
2054 return NULL;
2055 }
2056
2057 return task;
2058 }
2059
2060 struct scsi_task *
iscsi_synchronizecache10_task(struct iscsi_context * iscsi,int lun,int lba,int num_blocks,int syncnv,int immed,iscsi_command_cb cb,void * private_data)2061 iscsi_synchronizecache10_task(struct iscsi_context *iscsi, int lun, int lba,
2062 int num_blocks, int syncnv, int immed,
2063 iscsi_command_cb cb, void *private_data)
2064 {
2065 struct scsi_task *task;
2066
2067 task = scsi_cdb_synchronizecache10(lba, num_blocks, syncnv,
2068 immed);
2069 if (task == NULL) {
2070 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2071 "synchronizecache10 cdb.");
2072 return NULL;
2073 }
2074 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2075 NULL, private_data) != 0) {
2076 scsi_free_scsi_task(task);
2077 return NULL;
2078 }
2079
2080 return task;
2081 }
2082
2083 struct scsi_task *
iscsi_synchronizecache16_task(struct iscsi_context * iscsi,int lun,uint64_t lba,uint32_t num_blocks,int syncnv,int immed,iscsi_command_cb cb,void * private_data)2084 iscsi_synchronizecache16_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
2085 uint32_t num_blocks, int syncnv, int immed,
2086 iscsi_command_cb cb, void *private_data)
2087 {
2088 struct scsi_task *task;
2089
2090 task = scsi_cdb_synchronizecache16(lba, num_blocks, syncnv,
2091 immed);
2092 if (task == NULL) {
2093 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2094 "synchronizecache16 cdb.");
2095 return NULL;
2096 }
2097 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2098 NULL, private_data) != 0) {
2099 scsi_free_scsi_task(task);
2100 return NULL;
2101 }
2102
2103 return task;
2104 }
2105
2106 struct scsi_task *
iscsi_persistent_reserve_in_task(struct iscsi_context * iscsi,int lun,int sa,uint16_t xferlen,iscsi_command_cb cb,void * private_data)2107 iscsi_persistent_reserve_in_task(struct iscsi_context *iscsi, int lun,
2108 int sa, uint16_t xferlen,
2109 iscsi_command_cb cb, void *private_data)
2110 {
2111 struct scsi_task *task;
2112
2113 task = scsi_cdb_persistent_reserve_in(sa, xferlen);
2114 if (task == NULL) {
2115 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2116 "persistent-reserver-in cdb.");
2117 return NULL;
2118 }
2119 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2120 NULL, private_data) != 0) {
2121 scsi_free_scsi_task(task);
2122 return NULL;
2123 }
2124
2125 return task;
2126 }
2127
2128 struct scsi_task *
iscsi_persistent_reserve_out_task(struct iscsi_context * iscsi,int lun,int sa,int scope,int type,void * param,iscsi_command_cb cb,void * private_data)2129 iscsi_persistent_reserve_out_task(struct iscsi_context *iscsi, int lun,
2130 int sa, int scope, int type, void *param,
2131 iscsi_command_cb cb, void *private_data)
2132 {
2133 struct scsi_task *task;
2134
2135 task = scsi_cdb_persistent_reserve_out(sa, scope, type, param);
2136 if (task == NULL) {
2137 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2138 "persistent-reserver-out cdb.");
2139 return NULL;
2140 }
2141 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2142 NULL, private_data) != 0) {
2143 scsi_free_scsi_task(task);
2144 return NULL;
2145 }
2146
2147 return task;
2148 }
2149
2150 struct scsi_task *
iscsi_prefetch10_task(struct iscsi_context * iscsi,int lun,uint32_t lba,int num_blocks,int immed,int group,iscsi_command_cb cb,void * private_data)2151 iscsi_prefetch10_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
2152 int num_blocks, int immed, int group,
2153 iscsi_command_cb cb, void *private_data)
2154 {
2155 struct scsi_task *task;
2156
2157 task = scsi_cdb_prefetch10(lba, num_blocks, immed, group);
2158 if (task == NULL) {
2159 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2160 "prefetch10 cdb.");
2161 return NULL;
2162 }
2163 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2164 NULL, private_data) != 0) {
2165 scsi_free_scsi_task(task);
2166 return NULL;
2167 }
2168
2169 return task;
2170 }
2171
2172 struct scsi_task *
iscsi_prefetch16_task(struct iscsi_context * iscsi,int lun,uint64_t lba,int num_blocks,int immed,int group,iscsi_command_cb cb,void * private_data)2173 iscsi_prefetch16_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
2174 int num_blocks, int immed, int group,
2175 iscsi_command_cb cb, void *private_data)
2176 {
2177 struct scsi_task *task;
2178
2179 task = scsi_cdb_prefetch16(lba, num_blocks, immed, group);
2180 if (task == NULL) {
2181 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2182 "prefetch16 cdb.");
2183 return NULL;
2184 }
2185 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2186 NULL, private_data) != 0) {
2187 scsi_free_scsi_task(task);
2188 return NULL;
2189 }
2190
2191 return task;
2192 }
2193
2194 struct scsi_task *
iscsi_writesame10_task(struct iscsi_context * iscsi,int lun,uint32_t lba,unsigned char * data,uint32_t datalen,uint16_t num_blocks,int anchor,int unmap,int wrprotect,int group,iscsi_command_cb cb,void * private_data)2195 iscsi_writesame10_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
2196 unsigned char *data, uint32_t datalen,
2197 uint16_t num_blocks,
2198 int anchor, int unmap, int wrprotect, int group,
2199 iscsi_command_cb cb, void *private_data)
2200 {
2201 struct scsi_task *task;
2202 struct iscsi_data d;
2203
2204 task = scsi_cdb_writesame10(wrprotect, anchor, unmap, lba, group,
2205 num_blocks, datalen);
2206 if (task == NULL) {
2207 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2208 "writesame10 cdb.");
2209 return NULL;
2210 }
2211 d.data = data;
2212 d.size = datalen;
2213
2214 if (data != NULL) {
2215 task->expxferlen = datalen;
2216 } else {
2217 task->expxferlen = 0;
2218 task->xfer_dir = SCSI_XFER_NONE;
2219 }
2220 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2221 &d, private_data) != 0) {
2222 scsi_free_scsi_task(task);
2223 return NULL;
2224 }
2225 return task;
2226 }
2227
2228 struct scsi_task *
iscsi_writesame10_iov_task(struct iscsi_context * iscsi,int lun,uint32_t lba,unsigned char * data,uint32_t datalen,uint16_t num_blocks,int anchor,int unmap,int wrprotect,int group,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)2229 iscsi_writesame10_iov_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
2230 unsigned char *data, uint32_t datalen,
2231 uint16_t num_blocks,
2232 int anchor, int unmap, int wrprotect, int group,
2233 iscsi_command_cb cb, void *private_data,
2234 struct scsi_iovec *iov, int niov)
2235 {
2236 struct scsi_task *task;
2237 struct iscsi_data d;
2238
2239 task = scsi_cdb_writesame10(wrprotect, anchor, unmap, lba, group,
2240 num_blocks, datalen);
2241 if (task == NULL) {
2242 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2243 "writesame10 cdb.");
2244 return NULL;
2245 }
2246 d.data = data;
2247 d.size = datalen;
2248
2249 if (iov != NULL)
2250 scsi_task_set_iov_out(task, iov, niov);
2251
2252 if (data != NULL) {
2253 task->expxferlen = datalen;
2254 } else {
2255 task->expxferlen = 0;
2256 task->xfer_dir = SCSI_XFER_NONE;
2257 }
2258 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2259 &d, private_data) != 0) {
2260 scsi_free_scsi_task(task);
2261 return NULL;
2262 }
2263 return task;
2264 }
2265
2266 struct scsi_task *
iscsi_writesame16_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,uint32_t num_blocks,int anchor,int unmap,int wrprotect,int group,iscsi_command_cb cb,void * private_data)2267 iscsi_writesame16_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
2268 unsigned char *data, uint32_t datalen,
2269 uint32_t num_blocks,
2270 int anchor, int unmap, int wrprotect, int group,
2271 iscsi_command_cb cb, void *private_data)
2272 {
2273 struct scsi_task *task;
2274 struct iscsi_data d;
2275
2276 task = scsi_cdb_writesame16(wrprotect, anchor, unmap, lba, group,
2277 num_blocks, datalen);
2278 if (task == NULL) {
2279 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2280 "writesame16 cdb.");
2281 return NULL;
2282 }
2283 d.data = data;
2284 d.size = datalen;
2285
2286 if (data != NULL) {
2287 task->expxferlen = datalen;
2288 } else {
2289 task->expxferlen = 0;
2290 task->xfer_dir = SCSI_XFER_NONE;
2291 }
2292
2293 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2294 &d, private_data) != 0) {
2295 scsi_free_scsi_task(task);
2296 return NULL;
2297 }
2298
2299 return task;
2300 }
2301
2302 struct scsi_task *
iscsi_writesame16_iov_task(struct iscsi_context * iscsi,int lun,uint64_t lba,unsigned char * data,uint32_t datalen,uint32_t num_blocks,int anchor,int unmap,int wrprotect,int group,iscsi_command_cb cb,void * private_data,struct scsi_iovec * iov,int niov)2303 iscsi_writesame16_iov_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
2304 unsigned char *data, uint32_t datalen,
2305 uint32_t num_blocks,
2306 int anchor, int unmap, int wrprotect, int group,
2307 iscsi_command_cb cb, void *private_data,
2308 struct scsi_iovec *iov, int niov)
2309 {
2310 struct scsi_task *task;
2311 struct iscsi_data d;
2312
2313 task = scsi_cdb_writesame16(wrprotect, anchor, unmap, lba, group,
2314 num_blocks, datalen);
2315 if (task == NULL) {
2316 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2317 "writesame16 cdb.");
2318 return NULL;
2319 }
2320 d.data = data;
2321 d.size = datalen;
2322
2323 if (iov != NULL)
2324 scsi_task_set_iov_out(task, iov, niov);
2325
2326 if (data != NULL) {
2327 task->expxferlen = datalen;
2328 } else {
2329 task->expxferlen = 0;
2330 task->xfer_dir = SCSI_XFER_NONE;
2331 }
2332
2333 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2334 &d, private_data) != 0) {
2335 scsi_free_scsi_task(task);
2336 return NULL;
2337 }
2338
2339 return task;
2340 }
2341
2342 struct scsi_task *
iscsi_unmap_task(struct iscsi_context * iscsi,int lun,int anchor,int group,struct unmap_list * list,int list_len,iscsi_command_cb cb,void * private_data)2343 iscsi_unmap_task(struct iscsi_context *iscsi, int lun, int anchor, int group,
2344 struct unmap_list *list, int list_len,
2345 iscsi_command_cb cb, void *private_data)
2346 {
2347 struct scsi_task *task;
2348 struct scsi_iovec *iov;
2349 unsigned char *data;
2350 int xferlen;
2351 int i;
2352
2353 xferlen = 8 + list_len * 16;
2354
2355 task = scsi_cdb_unmap(anchor, group, xferlen);
2356 if (task == NULL) {
2357 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2358 "unmap cdb.");
2359 return NULL;
2360 }
2361
2362 data = scsi_malloc(task, xferlen);
2363 if (data == NULL) {
2364 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2365 "unmap parameters.");
2366 scsi_free_scsi_task(task);
2367 return NULL;
2368 }
2369 scsi_set_uint16(&data[0], xferlen - 2);
2370 scsi_set_uint16(&data[2], xferlen - 8);
2371 for (i = 0; i < list_len; i++) {
2372 scsi_set_uint32(&data[8 + 16 * i], list[i].lba >> 32);
2373 scsi_set_uint32(&data[8 + 16 * i + 4], list[i].lba & 0xffffffff);
2374 scsi_set_uint32(&data[8 + 16 * i + 8], list[i].num);
2375 }
2376
2377 iov = scsi_malloc(task, sizeof(struct scsi_iovec));
2378 if (iov == NULL) {
2379 scsi_free_scsi_task(task);
2380 return NULL;
2381 }
2382 iov->iov_base = data;
2383 iov->iov_len = xferlen;
2384 scsi_task_set_iov_out(task, iov, 1);
2385
2386 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2387 NULL, private_data) != 0) {
2388 scsi_free_scsi_task(task);
2389 return NULL;
2390 }
2391
2392 return task;
2393 }
2394
2395 struct scsi_iovector *
iscsi_get_scsi_task_iovector_in(struct iscsi_context * iscsi,struct iscsi_in_pdu * in)2396 iscsi_get_scsi_task_iovector_in(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
2397 {
2398 struct iscsi_pdu *pdu;
2399 uint32_t itt;
2400
2401 if ((in->hdr[0] & 0x3f) != ISCSI_PDU_DATA_IN) {
2402 return NULL;
2403 }
2404
2405 itt = scsi_get_uint32(&in->hdr[16]);
2406 for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) {
2407 if (pdu->itt == itt) {
2408 break;
2409 }
2410 }
2411
2412 if (pdu == NULL) {
2413 return NULL;
2414 }
2415
2416 if (pdu->scsi_cbdata.task->iovector_in.iov == NULL) {
2417 return NULL;
2418 }
2419
2420 return &pdu->scsi_cbdata.task->iovector_in;
2421 }
2422
2423 struct scsi_iovector *
iscsi_get_scsi_task_iovector_out(struct iscsi_context * iscsi _U_,struct iscsi_pdu * pdu)2424 iscsi_get_scsi_task_iovector_out(struct iscsi_context *iscsi _U_, struct iscsi_pdu *pdu)
2425 {
2426 if (pdu->scsi_cbdata.task->iovector_out.iov == NULL) {
2427 return NULL;
2428 }
2429
2430 return &pdu->scsi_cbdata.task->iovector_out;
2431 }
2432
2433 struct scsi_task *
iscsi_readtoc_task(struct iscsi_context * iscsi,int lun,int msf,int format,int track_session,int maxsize,iscsi_command_cb cb,void * private_data)2434 iscsi_readtoc_task(struct iscsi_context *iscsi, int lun, int msf,
2435 int format, int track_session, int maxsize,
2436 iscsi_command_cb cb, void *private_data)
2437 {
2438 struct scsi_task *task;
2439
2440 task = scsi_cdb_readtoc(msf, format, track_session, maxsize);
2441 if (task == NULL) {
2442 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2443 "read TOC cdb.");
2444 return NULL;
2445 }
2446 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2447 NULL, private_data) != 0) {
2448 scsi_free_scsi_task(task);
2449 return NULL;
2450 }
2451
2452 return task;
2453 }
2454
2455 struct scsi_task *
iscsi_reserve6_task(struct iscsi_context * iscsi,int lun,iscsi_command_cb cb,void * private_data)2456 iscsi_reserve6_task(struct iscsi_context *iscsi, int lun,
2457 iscsi_command_cb cb, void *private_data)
2458 {
2459 struct scsi_task *task;
2460
2461 task = scsi_cdb_reserve6();
2462 if (task == NULL) {
2463 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2464 "reserve6 cdb.");
2465 return NULL;
2466 }
2467 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2468 NULL, private_data) != 0) {
2469 scsi_free_scsi_task(task);
2470 return NULL;
2471 }
2472
2473 return task;
2474 }
2475
2476 struct scsi_task *
iscsi_release6_task(struct iscsi_context * iscsi,int lun,iscsi_command_cb cb,void * private_data)2477 iscsi_release6_task(struct iscsi_context *iscsi, int lun,
2478 iscsi_command_cb cb, void *private_data)
2479 {
2480 struct scsi_task *task;
2481
2482 task = scsi_cdb_release6();
2483 if (task == NULL) {
2484 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2485 "release6 cdb.");
2486 return NULL;
2487 }
2488 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2489 NULL, private_data) != 0) {
2490 scsi_free_scsi_task(task);
2491 return NULL;
2492 }
2493
2494 return task;
2495 }
2496
2497
2498 struct scsi_task *
iscsi_sanitize_task(struct iscsi_context * iscsi,int lun,int immed,int ause,int sa,int param_len,struct iscsi_data * data,iscsi_command_cb cb,void * private_data)2499 iscsi_sanitize_task(struct iscsi_context *iscsi, int lun,
2500 int immed, int ause, int sa, int param_len,
2501 struct iscsi_data *data,
2502 iscsi_command_cb cb, void *private_data)
2503 {
2504 struct scsi_task *task;
2505
2506 task = scsi_cdb_sanitize(immed, ause, sa, param_len);
2507 if (task == NULL) {
2508 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2509 "sanitize cdb.");
2510 return NULL;
2511 }
2512 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2513 data, private_data) != 0) {
2514 scsi_free_scsi_task(task);
2515 return NULL;
2516 }
2517
2518 return task;
2519 }
2520
2521 struct scsi_task *
iscsi_sanitize_block_erase_task(struct iscsi_context * iscsi,int lun,int immed,int ause,iscsi_command_cb cb,void * private_data)2522 iscsi_sanitize_block_erase_task(struct iscsi_context *iscsi, int lun,
2523 int immed, int ause,
2524 iscsi_command_cb cb, void *private_data)
2525 {
2526 struct scsi_task *task;
2527
2528 task = scsi_cdb_sanitize(immed, ause, SCSI_SANITIZE_BLOCK_ERASE, 0);
2529 if (task == NULL) {
2530 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2531 "sanitize cdb.");
2532 return NULL;
2533 }
2534 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2535 NULL, private_data) != 0) {
2536 scsi_free_scsi_task(task);
2537 return NULL;
2538 }
2539
2540 return task;
2541 }
2542
2543 struct scsi_task *
iscsi_sanitize_crypto_erase_task(struct iscsi_context * iscsi,int lun,int immed,int ause,iscsi_command_cb cb,void * private_data)2544 iscsi_sanitize_crypto_erase_task(struct iscsi_context *iscsi, int lun,
2545 int immed, int ause,
2546 iscsi_command_cb cb, void *private_data)
2547 {
2548 struct scsi_task *task;
2549
2550 task = scsi_cdb_sanitize(immed, ause, SCSI_SANITIZE_CRYPTO_ERASE, 0);
2551 if (task == NULL) {
2552 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2553 "sanitize cdb.");
2554 return NULL;
2555 }
2556 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2557 NULL, private_data) != 0) {
2558 scsi_free_scsi_task(task);
2559 return NULL;
2560 }
2561
2562 return task;
2563 }
2564
2565 struct scsi_task *
iscsi_sanitize_exit_failure_mode_task(struct iscsi_context * iscsi,int lun,int immed,int ause,iscsi_command_cb cb,void * private_data)2566 iscsi_sanitize_exit_failure_mode_task(struct iscsi_context *iscsi, int lun,
2567 int immed, int ause,
2568 iscsi_command_cb cb, void *private_data)
2569 {
2570 struct scsi_task *task;
2571
2572 task = scsi_cdb_sanitize(immed, ause,
2573 SCSI_SANITIZE_EXIT_FAILURE_MODE, 0);
2574 if (task == NULL) {
2575 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2576 "sanitize cdb.");
2577 return NULL;
2578 }
2579 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2580 NULL, private_data) != 0) {
2581 scsi_free_scsi_task(task);
2582 return NULL;
2583 }
2584
2585 return task;
2586 }
2587
2588 struct scsi_task *
iscsi_report_supported_opcodes_task(struct iscsi_context * iscsi,int lun,int rctd,int options,int opcode,int sa,uint32_t alloc_len,iscsi_command_cb cb,void * private_data)2589 iscsi_report_supported_opcodes_task(struct iscsi_context *iscsi, int lun,
2590 int rctd, int options,
2591 int opcode, int sa,
2592 uint32_t alloc_len,
2593 iscsi_command_cb cb, void *private_data)
2594 {
2595 struct scsi_task *task;
2596
2597 task = scsi_cdb_report_supported_opcodes(rctd, options, opcode, sa,
2598 alloc_len);
2599 if (task == NULL) {
2600 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2601 "Maintenance In/Read Supported Op Codes cdb.");
2602 return NULL;
2603 }
2604 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2605 NULL, private_data) != 0) {
2606 scsi_free_scsi_task(task);
2607 return NULL;
2608 }
2609
2610 return task;
2611 }
2612
2613 struct scsi_task *
iscsi_receive_copy_results_task(struct iscsi_context * iscsi,int lun,int sa,int list_id,int alloc_len,iscsi_command_cb cb,void * private_data)2614 iscsi_receive_copy_results_task(struct iscsi_context *iscsi, int lun,
2615 int sa, int list_id, int alloc_len,
2616 iscsi_command_cb cb, void *private_data)
2617 {
2618 struct scsi_task *task;
2619
2620 task = scsi_cdb_receive_copy_results(sa, list_id, alloc_len);
2621 if (task == NULL) {
2622 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2623 "RECEIVE COPY RESULTS cdb.");
2624 return NULL;
2625 }
2626
2627 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2628 NULL, private_data) != 0) {
2629 scsi_free_scsi_task(task);
2630 return NULL;
2631 }
2632
2633 return task;
2634 }
2635
2636 struct scsi_task *
iscsi_extended_copy_task(struct iscsi_context * iscsi,int lun,struct iscsi_data * param_data,iscsi_command_cb cb,void * private_data)2637 iscsi_extended_copy_task(struct iscsi_context *iscsi, int lun,
2638 struct iscsi_data *param_data,
2639 iscsi_command_cb cb, void *private_data)
2640 {
2641 struct scsi_task *task;
2642
2643 task = scsi_cdb_extended_copy(param_data->size);
2644 if (task == NULL) {
2645 iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
2646 "EXTENDED COPY cdb.");
2647 return NULL;
2648 }
2649
2650 if (iscsi_scsi_command_async(iscsi, lun, task, cb,
2651 param_data, private_data) != 0) {
2652 scsi_free_scsi_task(task);
2653 return NULL;
2654 }
2655
2656 return task;
2657 }
2658
2659 struct scsi_task *
iscsi_scsi_get_task_from_pdu(struct iscsi_pdu * pdu)2660 iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu)
2661 {
2662 return pdu->scsi_cbdata.task;
2663 }
2664
2665 int
iscsi_scsi_cancel_task(struct iscsi_context * iscsi,struct scsi_task * task)2666 iscsi_scsi_cancel_task(struct iscsi_context *iscsi,
2667 struct scsi_task *task)
2668 {
2669 struct iscsi_pdu *pdu;
2670
2671 for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) {
2672 if (pdu->itt == task->itt) {
2673 ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
2674 if (pdu->callback) {
2675 pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
2676 pdu->private_data);
2677 }
2678 iscsi->drv->free_pdu(iscsi, pdu);
2679 return 0;
2680 }
2681 }
2682 for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) {
2683 if (pdu->itt == task->itt) {
2684 ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
2685 if (pdu->callback) {
2686 pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
2687 pdu->private_data);
2688 }
2689 iscsi->drv->free_pdu(iscsi, pdu);
2690 return 0;
2691 }
2692 }
2693 return -1;
2694 }
2695
2696 void
iscsi_scsi_cancel_all_tasks(struct iscsi_context * iscsi)2697 iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi)
2698 {
2699 iscsi_cancel_pdus(iscsi);
2700 }
2701