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