xref: /spdk/lib/scsi/scsi_bdev.c (revision bea2e2308fc7a98826f3cfe36c584cfb14dcd180)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
5  *   Copyright (c) Intel Corporation.
6  *   All rights reserved.
7  *
8  *   Redistribution and use in source and binary forms, with or without
9  *   modification, are permitted provided that the following conditions
10  *   are met:
11  *
12  *     * Redistributions of source code must retain the above copyright
13  *       notice, this list of conditions and the following disclaimer.
14  *     * Redistributions in binary form must reproduce the above copyright
15  *       notice, this list of conditions and the following disclaimer in
16  *       the documentation and/or other materials provided with the
17  *       distribution.
18  *     * Neither the name of Intel Corporation nor the names of its
19  *       contributors may be used to endorse or promote products derived
20  *       from this software without specific prior written permission.
21  *
22  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include "scsi_internal.h"
36 
37 /*
38  * TODO: move bdev SCSI error code translation tests to bdev unit test
39  * and remove this include.
40  */
41 #include "spdk_internal/bdev.h"
42 
43 #include "spdk/env.h"
44 #include "spdk/bdev.h"
45 #include "spdk/endian.h"
46 #include "spdk/string.h"
47 #include "spdk/util.h"
48 
49 #define SPDK_WORK_BLOCK_SIZE		(1ULL * 1024ULL * 1024ULL)
50 #define SPDK_WORK_ATS_BLOCK_SIZE	(1ULL * 1024ULL * 1024ULL)
51 #define MAX_SERIAL_STRING		32
52 
53 #define DEFAULT_DISK_VENDOR		"INTEL"
54 #define DEFAULT_DISK_REVISION		"0001"
55 #define DEFAULT_DISK_ROTATION_RATE	1	/* Non-rotating medium */
56 #define DEFAULT_DISK_FORM_FACTOR	0x02	/* 3.5 inch */
57 
58 #define INQUIRY_OFFSET(field)		offsetof(struct spdk_scsi_cdb_inquiry_data, field) + \
59 					sizeof(((struct spdk_scsi_cdb_inquiry_data *)0x0)->field)
60 
61 static int
62 spdk_hex2bin(char ch)
63 {
64 	if ((ch >= '0') && (ch <= '9'))
65 		return ch - '0';
66 	ch = tolower(ch);
67 	if ((ch >= 'a') && (ch <= 'f'))
68 		return ch - 'a' + 10;
69 	return (int)ch;
70 }
71 
72 static void
73 spdk_bdev_scsi_set_local_naa(const char *name, uint8_t *buf)
74 {
75 	int i, value, count = 0;
76 	uint64_t naa, local_value;
77 
78 	for (i = 0; (i < 16) && (name[i] != '\0'); i++) {
79 		value = spdk_hex2bin(name[i]);
80 		if (i % 2) {
81 			buf[count++] |= value << 4;
82 		} else {
83 			buf[count] = value;
84 		}
85 	}
86 	/* NAA locally assigned filed */
87 	naa = 0x3;
88 	local_value = *(uint64_t *)buf;
89 	local_value = (naa << 60) | (local_value >> 4);
90 	to_be64((void *)buf, local_value);
91 }
92 
93 static int
94 spdk_bdev_scsi_report_luns(struct spdk_scsi_lun *lun,
95 			   int sel, uint8_t *data, int alloc_len)
96 {
97 	struct spdk_scsi_dev *dev;
98 	uint64_t fmt_lun, lun_id, method;
99 	int hlen, len = 0;
100 	int i;
101 
102 	if (alloc_len < 8)
103 		return -1;
104 
105 	if (sel == 0x00) {
106 		/* logical unit with addressing method */
107 	} else if (sel == 0x01) {
108 		/* well known logical unit */
109 	} else if (sel == 0x02) {
110 		/* logical unit */
111 	} else
112 		return -1;
113 
114 	/* LUN LIST LENGTH */
115 	memset(data, 0, 4);
116 
117 	/* Reserved */
118 	memset(&data[4], 0, 4);
119 	hlen = 8;
120 
121 	dev = lun->dev;
122 	for (i = 0; i < dev->maxlun; i++) {
123 		if (dev->lun[i] == NULL)
124 			continue;
125 
126 		if (alloc_len - (hlen + len) < 8)
127 			return -1;
128 
129 		lun_id = (uint64_t)i;
130 
131 		if (dev->maxlun <= 0x0100) {
132 			/* below 256 */
133 			method = 0x00U;
134 			fmt_lun = (method & 0x03U) << 62;
135 			fmt_lun |= (lun_id & 0x00ffU) << 48;
136 		} else if (dev->maxlun <= 0x4000) {
137 			/* below 16384 */
138 			method = 0x01U;
139 			fmt_lun = (method & 0x03U) << 62;
140 			fmt_lun |= (lun_id & 0x3fffU) << 48;
141 		} else {
142 			/* XXX */
143 			fmt_lun = 0;
144 		}
145 
146 		/* LUN */
147 		to_be64(&data[hlen + len], fmt_lun);
148 		len += 8;
149 	}
150 
151 	/* LUN LIST LENGTH */
152 	to_be32(data, len);
153 
154 	return hlen + len;
155 }
156 
157 static int
158 spdk_bdev_scsi_inquiry(struct spdk_bdev *bdev, struct spdk_scsi_task *task,
159 		       uint8_t *cdb, uint8_t *data, uint16_t alloc_len)
160 {
161 	struct spdk_scsi_lun	*lun;
162 	struct spdk_scsi_dev	*dev;
163 	struct spdk_scsi_port	*port;
164 	uint32_t blocks, optimal_blocks;
165 	int hlen = 0, plen, plen2;
166 	uint16_t len = 0;
167 	int pc;
168 	int pd;
169 	int evpd;
170 	int i;
171 	struct spdk_scsi_cdb_inquiry *inq = (struct spdk_scsi_cdb_inquiry *)cdb;
172 
173 	/* standard inquiry command at lease with 36 Bytes */
174 	if (alloc_len < 0x24)
175 		goto inq_error;
176 
177 	lun = task->lun;
178 	dev = lun->dev;
179 	port = task->target_port;
180 
181 	pd = SPDK_SPC_PERIPHERAL_DEVICE_TYPE_DISK;
182 	pc = inq->page_code;
183 	evpd = inq->evpd & 0x1;
184 
185 	if (!evpd && pc) {
186 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
187 					  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
188 					  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
189 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
190 		return -1;
191 	}
192 
193 	if (evpd) {
194 		struct spdk_scsi_vpd_page *vpage = (struct spdk_scsi_vpd_page *)data;
195 
196 		/* PERIPHERAL QUALIFIER(7-5) PERIPHERAL DEVICE TYPE(4-0) */
197 		vpage->peripheral = pd;
198 		/* PAGE CODE */
199 		vpage->page_code = pc;
200 
201 		/* Vital product data */
202 		switch (pc) {
203 		case SPDK_SPC_VPD_SUPPORTED_VPD_PAGES:
204 			hlen = 4;
205 
206 			vpage->params[0] = SPDK_SPC_VPD_SUPPORTED_VPD_PAGES;
207 			vpage->params[1] = SPDK_SPC_VPD_UNIT_SERIAL_NUMBER;
208 			vpage->params[2] = SPDK_SPC_VPD_DEVICE_IDENTIFICATION;
209 			vpage->params[3] = SPDK_SPC_VPD_MANAGEMENT_NETWORK_ADDRESSES;
210 			vpage->params[4] = SPDK_SPC_VPD_EXTENDED_INQUIRY_DATA;
211 			vpage->params[5] = SPDK_SPC_VPD_MODE_PAGE_POLICY;
212 			vpage->params[6] = SPDK_SPC_VPD_SCSI_PORTS;
213 			/* SBC Block Limits */
214 			vpage->params[7] = 0xb0;
215 			/* SBC Block Device Characteristics */
216 			vpage->params[8] = 0xb1;
217 			len = 9;
218 			if (spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_UNMAP)) {
219 				/* SBC Thin Provisioning */
220 				vpage->params[9] = 0xb2;
221 				len++;
222 			}
223 
224 			/* PAGE LENGTH */
225 			to_be16(vpage->alloc_len, len);
226 			break;
227 
228 		case SPDK_SPC_VPD_UNIT_SERIAL_NUMBER: {
229 			const char *name = spdk_bdev_get_name(bdev);
230 
231 			hlen = 4;
232 
233 			/* PRODUCT SERIAL NUMBER */
234 			len = strlen(name) + 1;
235 			if (len > MAX_SERIAL_STRING) {
236 				len = MAX_SERIAL_STRING;
237 			}
238 
239 			memcpy(vpage->params, name, len - 1);
240 			vpage->params[len - 1] = 0;
241 
242 			/* PAGE LENGTH */
243 			to_be16(vpage->alloc_len, len);
244 			break;
245 		}
246 
247 		case SPDK_SPC_VPD_DEVICE_IDENTIFICATION: {
248 			const char *name = spdk_bdev_get_name(bdev);
249 			const char *product_name = spdk_bdev_get_product_name(bdev);
250 			uint8_t *buf = vpage->params;
251 			struct spdk_scsi_desig_desc *desig;
252 
253 			hlen = 4;
254 
255 			/* Check total length by calculated how much space all entries take */
256 			len = sizeof(struct spdk_scsi_desig_desc) + 8;
257 			len += sizeof(struct spdk_scsi_desig_desc) + 8 + 16 + MAX_SERIAL_STRING;
258 			len += sizeof(struct spdk_scsi_desig_desc) + SPDK_SCSI_DEV_MAX_NAME;
259 			len += sizeof(struct spdk_scsi_desig_desc) + SPDK_SCSI_PORT_MAX_NAME_LENGTH;
260 			len += sizeof(struct spdk_scsi_desig_desc) + 4;
261 			len += sizeof(struct spdk_scsi_desig_desc) + 4;
262 			len += sizeof(struct spdk_scsi_desig_desc) + 4;
263 			if (sizeof(struct spdk_scsi_vpd_page) + len > alloc_len) {
264 				spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
265 							  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
266 							  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
267 							  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
268 				return -1;
269 			}
270 
271 			/* Now fill out the designator array */
272 
273 			/* NAA designator */
274 			desig = (struct spdk_scsi_desig_desc *)buf;
275 			desig->code_set = SPDK_SPC_VPD_CODE_SET_BINARY;
276 			desig->protocol_id = SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI;
277 			desig->type = SPDK_SPC_VPD_IDENTIFIER_TYPE_NAA;
278 			desig->association = SPDK_SPC_VPD_ASSOCIATION_LOGICAL_UNIT;
279 			desig->reserved0 = 0;
280 			desig->piv = 1;
281 			desig->reserved1 = 0;
282 			desig->len = 8;
283 			spdk_bdev_scsi_set_local_naa(name, desig->desig);
284 			len = sizeof(struct spdk_scsi_desig_desc) + 8;
285 
286 			buf += sizeof(struct spdk_scsi_desig_desc) + desig->len;
287 
288 			/* T10 Vendor ID designator */
289 			desig = (struct spdk_scsi_desig_desc *)buf;
290 			desig->code_set = SPDK_SPC_VPD_CODE_SET_ASCII;
291 			desig->protocol_id = SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI;
292 			desig->type = SPDK_SPC_VPD_IDENTIFIER_TYPE_T10_VENDOR_ID;
293 			desig->association = SPDK_SPC_VPD_ASSOCIATION_LOGICAL_UNIT;
294 			desig->reserved0 = 0;
295 			desig->piv = 1;
296 			desig->reserved1 = 0;
297 			desig->len = 8 + 16 + MAX_SERIAL_STRING;
298 			spdk_strcpy_pad(desig->desig, DEFAULT_DISK_VENDOR, 8, ' ');
299 			spdk_strcpy_pad(&desig->desig[8], product_name, 16, ' ');
300 			spdk_strcpy_pad(&desig->desig[24], name, MAX_SERIAL_STRING, ' ');
301 			len += sizeof(struct spdk_scsi_desig_desc) + 8 + 16 + MAX_SERIAL_STRING;
302 
303 			buf += sizeof(struct spdk_scsi_desig_desc) + desig->len;
304 
305 			/* SCSI Device Name designator */
306 			desig = (struct spdk_scsi_desig_desc *)buf;
307 			desig->code_set = SPDK_SPC_VPD_CODE_SET_UTF8;
308 			desig->protocol_id = SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI;
309 			desig->type = SPDK_SPC_VPD_IDENTIFIER_TYPE_SCSI_NAME;
310 			desig->association = SPDK_SPC_VPD_ASSOCIATION_TARGET_DEVICE;
311 			desig->reserved0 = 0;
312 			desig->piv = 1;
313 			desig->reserved1 = 0;
314 			desig->len = snprintf(desig->desig, SPDK_SCSI_DEV_MAX_NAME, "%s", dev->name);
315 			len += sizeof(struct spdk_scsi_desig_desc) + desig->len;
316 
317 			buf += sizeof(struct spdk_scsi_desig_desc) + desig->len;
318 
319 			/* SCSI Port Name designator */
320 			desig = (struct spdk_scsi_desig_desc *)buf;
321 			desig->code_set = SPDK_SPC_VPD_CODE_SET_UTF8;
322 			desig->protocol_id = SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI;
323 			desig->type = SPDK_SPC_VPD_IDENTIFIER_TYPE_SCSI_NAME;
324 			desig->association = SPDK_SPC_VPD_ASSOCIATION_TARGET_PORT;
325 			desig->reserved0 = 0;
326 			desig->piv = 1;
327 			desig->reserved1 = 0;
328 			desig->len = snprintf(desig->desig, SPDK_SCSI_PORT_MAX_NAME_LENGTH, "%s", port->name);
329 			len += sizeof(struct spdk_scsi_desig_desc) + desig->len;
330 
331 			buf += sizeof(struct spdk_scsi_desig_desc) + desig->len;
332 
333 			/* Relative Target Port designator */
334 			desig = (struct spdk_scsi_desig_desc *)buf;
335 			desig->code_set = SPDK_SPC_VPD_CODE_SET_BINARY;
336 			desig->protocol_id = SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI;
337 			desig->type = SPDK_SPC_VPD_IDENTIFIER_TYPE_RELATIVE_TARGET_PORT;
338 			desig->association = SPDK_SPC_VPD_ASSOCIATION_TARGET_PORT;
339 			desig->reserved0 = 0;
340 			desig->piv = 1;
341 			desig->reserved1 = 0;
342 			desig->len = 4;
343 			memset(desig->desig, 0, 2); /* Reserved */
344 			to_be16(&desig->desig[2], port->index);
345 			len += sizeof(struct spdk_scsi_desig_desc) + desig->len;
346 
347 			buf += sizeof(struct spdk_scsi_desig_desc) + desig->len;
348 
349 			/* Target port group designator */
350 			desig = (struct spdk_scsi_desig_desc *)buf;
351 			desig->code_set = SPDK_SPC_VPD_CODE_SET_BINARY;
352 			desig->protocol_id = SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI;
353 			desig->type = SPDK_SPC_VPD_IDENTIFIER_TYPE_TARGET_PORT_GROUP;
354 			desig->association = SPDK_SPC_VPD_ASSOCIATION_TARGET_PORT;
355 			desig->reserved0 = 0;
356 			desig->piv = 1;
357 			desig->reserved1 = 0;
358 			desig->len = 4;
359 			memset(desig->desig, 0, 4);
360 			len += sizeof(struct spdk_scsi_desig_desc) + desig->len;
361 
362 			buf += sizeof(struct spdk_scsi_desig_desc) + desig->len;
363 
364 			/* Logical unit group designator */
365 			desig = (struct spdk_scsi_desig_desc *)buf;
366 			desig->code_set = SPDK_SPC_VPD_CODE_SET_BINARY;
367 			desig->protocol_id = SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI;
368 			desig->type = SPDK_SPC_VPD_IDENTIFIER_TYPE_LOGICAL_UNIT_GROUP;
369 			desig->association = SPDK_SPC_VPD_ASSOCIATION_LOGICAL_UNIT;
370 			desig->reserved0 = 0;
371 			desig->piv = 1;
372 			desig->reserved1 = 0;
373 			desig->len = 4;
374 			memset(desig->desig, 0, 2); /* Reserved */
375 			to_be16(&desig->desig[2], dev->id);
376 			len += sizeof(struct spdk_scsi_desig_desc) + desig->len;
377 
378 			to_be16(vpage->alloc_len, len);
379 
380 			break;
381 		}
382 
383 		case SPDK_SPC_VPD_EXTENDED_INQUIRY_DATA: {
384 			struct spdk_scsi_vpd_ext_inquiry *vext = (struct spdk_scsi_vpd_ext_inquiry *)vpage;
385 
386 			memset(vext, 0, sizeof(*vext));
387 			hlen = 4;
388 
389 			/* RTO(3) GRD_CHK(2) APP_CHK(1) REF_CHK(0) */
390 
391 			/* GROUP_SUP(4) PRIOR_SUP(3) HEADSUP(2) ORDSUP(1) SIMPSUP(0) */
392 			vext->sup = SPDK_SCSI_VEXT_HEADSUP | SPDK_SCSI_VEXT_SIMPSUP;
393 
394 			/* NV_SUP(1) V_SUP(0) */
395 
396 			/* Reserved[7-63] */
397 
398 			len = 64 - hlen;
399 
400 			/* PAGE LENGTH */
401 			to_be16(vpage->alloc_len, len);
402 			break;
403 		}
404 
405 		case SPDK_SPC_VPD_MANAGEMENT_NETWORK_ADDRESSES:
406 			/* PAGE LENGTH */
407 			hlen = 4;
408 
409 			to_be16(vpage->alloc_len, len);
410 			break;
411 
412 		case SPDK_SPC_VPD_MODE_PAGE_POLICY: {
413 			struct spdk_scsi_mpage_policy_desc *pdesc =
414 				(struct spdk_scsi_mpage_policy_desc *)vpage->params;
415 
416 			hlen = 4;
417 
418 			/* Mode page policy descriptor 1 */
419 
420 			/* POLICY PAGE CODE(5-0) */
421 			/* all page code */
422 			pdesc->page_code = 0x3f;
423 
424 			/* POLICY SUBPAGE CODE */
425 			/* all sub page */
426 			pdesc->sub_page_code = 0xff;
427 
428 			/* MLUS(7) MODE PAGE POLICY(1-0) */
429 			/* MLUS own copy */
430 			/* Shared MODE PAGE policy */
431 			pdesc->policy = 0;
432 			/* Reserved */
433 			pdesc->reserved = 0;
434 
435 			len += 4;
436 
437 			to_be16(vpage->alloc_len, len);
438 			break;
439 		}
440 
441 		case SPDK_SPC_VPD_SCSI_PORTS: {
442 			/* PAGE LENGTH */
443 			hlen = 4;
444 
445 			/* Identification descriptor list */
446 			for (i = 0; i < dev->num_ports; i++) {
447 				struct spdk_scsi_port_desc *sdesc;
448 				struct spdk_scsi_tgt_port_desc *pdesc;
449 
450 				/* Identification descriptor N */
451 				sdesc = (struct spdk_scsi_port_desc *)&vpage->params[len];
452 
453 				/* Reserved */
454 				sdesc->reserved = 0;
455 
456 				/* RELATIVE PORT IDENTIFIER */
457 				to_be16(&sdesc->rel_port_id, dev->port[i].index);
458 
459 				/* Reserved */
460 				sdesc->reserved2 = 0;
461 
462 				/* INITIATOR PORT TRANSPORTID LENGTH */
463 				sdesc->init_port_len = 0;
464 
465 				/* Reserved */
466 				sdesc->init_port_id = 0;
467 
468 				/* TARGET PORT DESCRIPTORS LENGTH */
469 				sdesc->tgt_desc_len = 0;
470 
471 				len += 12;
472 
473 				plen2 = 0;
474 				/* Target port descriptor 1 */
475 				pdesc = (struct spdk_scsi_tgt_port_desc *)sdesc->tgt_desc;
476 
477 				/* PROTOCOL IDENTIFIER(7-4) CODE SET(3-0) */
478 				pdesc->code_set =
479 					SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI << 4 |
480 					SPDK_SPC_VPD_CODE_SET_UTF8;
481 
482 				/* PIV(7) ASSOCIATION(5-4) IDENTIFIER TYPE(3-0) */
483 				pdesc->desig_type = SPDK_SPC_VPD_DESIG_PIV |
484 						    SPDK_SPC_VPD_ASSOCIATION_TARGET_PORT << 4 |
485 						    SPDK_SPC_VPD_IDENTIFIER_TYPE_SCSI_NAME;
486 
487 				/* Reserved */
488 				pdesc->reserved = 0;
489 
490 				/* IDENTIFIER */
491 				plen = snprintf((char *)pdesc->designator,
492 						SPDK_SCSI_PORT_MAX_NAME_LENGTH, "%s",
493 						dev->port[i].name);
494 				pdesc->len = plen;
495 
496 				plen2 += 4 + plen;
497 
498 				/* TARGET PORT DESCRIPTORS LENGTH */
499 				to_be16(&sdesc->tgt_desc_len, plen2);
500 
501 				len += plen2;
502 			}
503 
504 			to_be16(vpage->alloc_len, len);
505 			break;
506 		}
507 
508 		case SPDK_SPC_VPD_BLOCK_LIMITS: {
509 			uint32_t block_size = spdk_bdev_get_block_size(bdev);
510 
511 			/* PAGE LENGTH */
512 			memset(&data[4], 0, 60);
513 
514 			hlen = 4;
515 
516 			/* WSNZ(0) */
517 			/* support zero length in WRITE SAME */
518 
519 			/* MAXIMUM COMPARE AND WRITE LENGTH */
520 			blocks = SPDK_WORK_ATS_BLOCK_SIZE / block_size;
521 
522 			if (blocks > 0xff)
523 				blocks = 0xff;
524 
525 			data[5] = (uint8_t)blocks;
526 
527 			/* force align to 4KB */
528 			if (block_size < 4096) {
529 				optimal_blocks = 4096 / block_size;
530 			} else {
531 				optimal_blocks = 1;
532 			}
533 
534 			/* OPTIMAL TRANSFER LENGTH GRANULARITY */
535 			to_be16(&data[6], optimal_blocks);
536 
537 			blocks = SPDK_WORK_BLOCK_SIZE / block_size;
538 
539 			/* MAXIMUM TRANSFER LENGTH */
540 			to_be32(&data[8], blocks);
541 			/* OPTIMAL TRANSFER LENGTH */
542 			to_be32(&data[12], blocks);
543 
544 			/* MAXIMUM PREFETCH XDREAD XDWRITE TRANSFER LENGTH */
545 
546 			len = 20 - hlen;
547 
548 			if (spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_UNMAP)) {
549 				uint32_t max_unmap_desc;
550 
551 				/*
552 				 * MAXIMUM UNMAP LBA COUNT: indicates the
553 				 * maximum  number of LBAs that may be
554 				 * unmapped by an UNMAP command.
555 				 */
556 				to_be32(&data[20], g_spdk_scsi.scsi_params.max_unmap_lba_count);
557 
558 				/*
559 				 * MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT:
560 				 * indicates the maximum number of UNMAP
561 				 * block descriptors that shall be contained
562 				 * in the parameter data transferred to the
563 				 * device server for an UNMAP command.
564 				 */
565 				max_unmap_desc = spdk_min(spdk_bdev_get_max_unmap_descriptors(bdev),
566 							  g_spdk_scsi.scsi_params.max_unmap_block_descriptor_count);
567 				to_be32(&data[24], max_unmap_desc);
568 
569 				/*
570 				 * OPTIMAL UNMAP GRANULARITY: indicates the
571 				 * optimal granularity in logical blocks
572 				 * for unmap request.
573 				 */
574 				to_be32(&data[28], g_spdk_scsi.scsi_params.optimal_unmap_granularity);
575 
576 				/*
577 				 * UNMAP GRANULARITY ALIGNMENT: indicates the
578 				 * LBA of the first logical block to which the
579 				 * OPTIMAL UNMAP GRANULARITY field applies.
580 				 */
581 				/* not specified */
582 				to_be32(&data[32], g_spdk_scsi.scsi_params.unmap_granularity_alignment);
583 
584 				/*
585 				 * UGAVALID(7): bit set to one indicates that
586 				 * the UNMAP GRANULARITY ALIGNMENT field is
587 				 * valid.
588 				 */
589 				/* not specified */
590 				if (g_spdk_scsi.scsi_params.ugavalid)
591 					data[32] |= 1 << 7;
592 
593 				/*
594 				 * MAXIMUM WRITE SAME LENGTH: indicates the
595 				 * maximum number of contiguous logical blocks
596 				 * that the device server allows to be unmapped
597 				 * or written in a single WRITE SAME command.
598 				 */
599 				to_be64(&data[36], g_spdk_scsi.scsi_params.max_write_same_length);
600 
601 				/* Reserved */
602 				/* not specified */
603 				len = 64 - hlen;
604 			}
605 
606 			to_be16(vpage->alloc_len, len);
607 			break;
608 		}
609 
610 		case SPDK_SPC_VPD_BLOCK_DEV_CHARS: {
611 			/* PAGE LENGTH */
612 			hlen = 4;
613 			len = 64 - hlen;
614 
615 			to_be16(&data[4], DEFAULT_DISK_ROTATION_RATE);
616 
617 			/* Reserved */
618 			data[6] = 0;
619 			/* NOMINAL FORM FACTOR(3-0) */
620 			data[7] = DEFAULT_DISK_FORM_FACTOR << 4;
621 			/* Reserved */
622 			memset(&data[8], 0, 64 - 8);
623 
624 			to_be16(vpage->alloc_len, len);
625 			break;
626 		}
627 
628 		case SPDK_SPC_VPD_BLOCK_THIN_PROVISION: {
629 			if (!spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_UNMAP)) {
630 				SPDK_ERRLOG("unsupported INQUIRY VPD page 0x%x\n", pc);
631 				goto inq_error;
632 			}
633 
634 			hlen = 4;
635 			len = 7;
636 
637 			/*
638 			 *  PAGE LENGTH : if the DP bit is set to one, then the
639 			 *  page length shall be set  0004h.
640 			 */
641 			to_be16(&data[2], 0x0004);
642 
643 			/*
644 			 * THRESHOLD EXPONENT : it indicates the threshold set
645 			 * size in LBAs as a power of 2( i.e., the threshold
646 			 * set size  = 2 ^ (threshold exponent).
647 			 */
648 			data[4] = 0;
649 
650 			/*
651 			 * Set the LBPU bit to indicate  the support for UNMAP
652 			 * command.
653 			 */
654 			data[5] |= SPDK_SCSI_UNMAP_LBPU;
655 
656 			/*
657 			 * Set the provisioning type to thin provision.
658 			 */
659 			data[6] = SPDK_SCSI_UNMAP_THIN_PROVISIONING;
660 
661 			to_be16(vpage->alloc_len, len);
662 			break;
663 		}
664 
665 		default:
666 			if (pc >= 0xc0 && pc <= 0xff) {
667 				SPDK_TRACELOG(SPDK_TRACE_SCSI, "Vendor specific INQUIRY VPD page 0x%x\n", pc);
668 			} else {
669 				SPDK_ERRLOG("unsupported INQUIRY VPD page 0x%x\n", pc);
670 			}
671 			goto inq_error;
672 		}
673 	} else {
674 		struct spdk_scsi_cdb_inquiry_data *inqdata =
675 			(struct spdk_scsi_cdb_inquiry_data *)data;
676 
677 		/* Standard INQUIRY data */
678 		/* PERIPHERAL QUALIFIER(7-5) PERIPHERAL DEVICE TYPE(4-0) */
679 		inqdata->peripheral = pd;
680 
681 		/* RMB(7) */
682 		inqdata->rmb = 0;
683 
684 		/* VERSION */
685 		/* See SPC3/SBC2/MMC4/SAM2 for more details */
686 		inqdata->version = SPDK_SPC_VERSION_SPC3;
687 
688 		/* NORMACA(5) HISUP(4) RESPONSE DATA FORMAT(3-0) */
689 		/* format 2 */ /* hierarchical support */
690 		inqdata->response = 2 | 1 << 4;
691 
692 		hlen = 5;
693 
694 		/* SCCS(7) ACC(6) TPGS(5-4) 3PC(3) PROTECT(0) */
695 		/* Not support TPGS */
696 		inqdata->flags = 0;
697 
698 		/* MULTIP */
699 		inqdata->flags2 = 0x10;
700 
701 		/* WBUS16(5) SYNC(4) LINKED(3) CMDQUE(1) VS(0) */
702 		/* CMDQUE */
703 		inqdata->flags3 = 0x2;
704 
705 		/* T10 VENDOR IDENTIFICATION */
706 		spdk_strcpy_pad(inqdata->t10_vendor_id, DEFAULT_DISK_VENDOR, 8, ' ');
707 
708 		/* PRODUCT IDENTIFICATION */
709 		spdk_strcpy_pad(inqdata->product_id, spdk_bdev_get_product_name(bdev), 16, ' ');
710 
711 		/* PRODUCT REVISION LEVEL */
712 		spdk_strcpy_pad(inqdata->product_rev, DEFAULT_DISK_REVISION, 4, ' ');
713 
714 		/*
715 		 * Standard inquiry data ends here.  Only populate remaining fields if alloc_len
716 		 *  indicates enough space to hold it.
717 		 */
718 		len = INQUIRY_OFFSET(product_rev) - 5;
719 
720 		if (alloc_len >= INQUIRY_OFFSET(vendor)) {
721 			/* Vendor specific */
722 			memset(inqdata->vendor, 0x20, 20);
723 			len += sizeof(inqdata->vendor);
724 		}
725 
726 		if (alloc_len >= INQUIRY_OFFSET(ius)) {
727 			/* CLOCKING(3-2) QAS(1) IUS(0) */
728 			inqdata->ius = 0;
729 			len += sizeof(inqdata->ius);
730 		}
731 
732 		if (alloc_len >= INQUIRY_OFFSET(reserved)) {
733 			/* Reserved */
734 			inqdata->reserved = 0;
735 			len += sizeof(inqdata->reserved);
736 		}
737 
738 		/* VERSION DESCRIPTOR 1-8 */
739 		if (alloc_len >= INQUIRY_OFFSET(reserved) + 2) {
740 			to_be16(&inqdata->desc[0], 0x0960);
741 			len += 2;
742 		}
743 
744 		if (alloc_len >= INQUIRY_OFFSET(reserved) + 4) {
745 			to_be16(&inqdata->desc[2], 0x0300); /* SPC-3 (no version claimed) */
746 			len += 2;
747 		}
748 
749 		if (alloc_len >= INQUIRY_OFFSET(reserved) + 6) {
750 			to_be16(&inqdata->desc[4], 0x320); /* SBC-2 (no version claimed) */
751 			len += 2;
752 		}
753 
754 		if (alloc_len >= INQUIRY_OFFSET(reserved) + 8) {
755 			to_be16(&inqdata->desc[6], 0x0040); /* SAM-2 (no version claimed) */
756 			len += 2;
757 		}
758 
759 		/*
760 		 * We only fill out 4 descriptors, but if the allocation length goes past
761 		 *  that, zero the remaining bytes.  This fixes some SCSI compliance tests
762 		 *  which expect a full 96 bytes to be returned, including the unpopulated
763 		 *  version descriptors 5-8 (4 * 2 = 8 bytes) plus the 22 bytes of reserved
764 		 *  space (bytes 74-95) - for a total of 30 bytes.
765 		 */
766 		if (alloc_len > INQUIRY_OFFSET(reserved) + 8) {
767 			i = alloc_len - (INQUIRY_OFFSET(reserved) + 8);
768 			if (i > 30) {
769 				i = 30;
770 			}
771 			memset(&inqdata->desc[8], 0, i);
772 			len += i;
773 		}
774 
775 		/* ADDITIONAL LENGTH */
776 		inqdata->add_len = len;
777 	}
778 
779 	return hlen + len;
780 
781 inq_error:
782 	task->data_transferred = 0;
783 	spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
784 				  SPDK_SCSI_SENSE_NO_SENSE,
785 				  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
786 				  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
787 	return -1;
788 }
789 
790 static void
791 mode_sense_page_init(uint8_t *buf, int len, int page, int subpage)
792 {
793 	if (!buf)
794 		return;
795 
796 	memset(buf, 0, len);
797 	if (subpage != 0) {
798 		buf[0] = page | 0x40; /* PAGE + SPF=1 */
799 		buf[1] = subpage;
800 		to_be16(&buf[2], len - 4);
801 	} else {
802 		buf[0] = page;
803 		buf[1] = len - 2;
804 	}
805 }
806 
807 static int
808 spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
809 			       uint8_t *cdb, int pc, int page, int subpage,
810 			       uint8_t *data, struct spdk_scsi_task *task)
811 {
812 	uint8_t *cp = data;
813 	int len = 0;
814 	int plen;
815 	int i;
816 
817 	if (pc == 0x00) {
818 		/* Current values */
819 	} else if (pc == 0x01) {
820 		/* Changeable values */
821 		/* As we currently do not support changeable values,
822 		   all parameters are reported as zero. */
823 	} else if (pc == 0x02) {
824 		/* Default values */
825 	} else {
826 		/* Saved values not supported */
827 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
828 					  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
829 					  SPDK_SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED,
830 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
831 		return -1;
832 	}
833 
834 	switch (page) {
835 	case 0x00:
836 		/* Vendor specific */
837 		break;
838 	case 0x01:
839 		/* Read-Write Error Recovery */
840 		SPDK_TRACELOG(SPDK_TRACE_SCSI,
841 			      "MODE_SENSE Read-Write Error Recovery\n");
842 		if (subpage != 0x00)
843 			break;
844 		plen = 0x0a + 2;
845 		mode_sense_page_init(cp, plen, page, subpage);
846 		len += plen;
847 		break;
848 	case 0x02:
849 		/* Disconnect-Reconnect */
850 		SPDK_TRACELOG(SPDK_TRACE_SCSI,
851 			      "MODE_SENSE Disconnect-Reconnect\n");
852 		if (subpage != 0x00)
853 			break;
854 		plen = 0x0e + 2;
855 		mode_sense_page_init(cp, plen, page, subpage);
856 		len += plen;
857 		break;
858 	case 0x03:
859 		/* Obsolete (Format Device) */
860 		break;
861 	case 0x04:
862 		/* Obsolete (Rigid Disk Geometry) */
863 		break;
864 	case 0x05:
865 		/* Obsolete (Rigid Disk Geometry) */
866 		break;
867 	case 0x06:
868 		/* Reserved */
869 		break;
870 	case 0x07:
871 		/* Verify Error Recovery */
872 		SPDK_TRACELOG(SPDK_TRACE_SCSI,
873 			      "MODE_SENSE Verify Error Recovery\n");
874 
875 		if (subpage != 0x00)
876 			break;
877 
878 		plen = 0x0a + 2;
879 		mode_sense_page_init(cp, plen, page, subpage);
880 		len += plen;
881 		break;
882 	case 0x08: {
883 		/* Caching */
884 		SPDK_TRACELOG(SPDK_TRACE_SCSI, "MODE_SENSE Caching\n");
885 		if (subpage != 0x00)
886 			break;
887 
888 		plen = 0x12 + 2;
889 		mode_sense_page_init(cp, plen, page, subpage);
890 
891 		if (cp && spdk_bdev_has_write_cache(bdev) && pc != 0x01)
892 			cp[2] |= 0x4; /* WCE */
893 
894 		/* Read Cache Disable (RCD) = 1 */
895 		if (cp && pc != 0x01)
896 			cp[2] |= 0x1;
897 
898 		len += plen;
899 		break;
900 	}
901 	case 0x09:
902 		/* Obsolete */
903 		break;
904 	case 0x0a:
905 		switch (subpage) {
906 		case 0x00:
907 			/* Control */
908 			SPDK_TRACELOG(SPDK_TRACE_SCSI,
909 				      "MODE_SENSE Control\n");
910 			plen = 0x0a + 2;
911 			mode_sense_page_init(cp, plen, page, subpage);
912 			len += plen;
913 			break;
914 		case 0x01:
915 			/* Control Extension */
916 			SPDK_TRACELOG(SPDK_TRACE_SCSI,
917 				      "MODE_SENSE Control Extension\n");
918 			plen = 0x1c + 4;
919 			mode_sense_page_init(cp, plen, page, subpage);
920 			len += plen;
921 			break;
922 		case 0xff:
923 			/* All subpages */
924 			len += spdk_bdev_scsi_mode_sense_page(bdev,
925 							      cdb, pc, page,
926 							      0x00,
927 							      cp ? &cp[len] : NULL, task);
928 			len += spdk_bdev_scsi_mode_sense_page(bdev,
929 							      cdb, pc, page,
930 							      0x01,
931 							      cp ? &cp[len] : NULL, task);
932 			break;
933 		default:
934 			/* 0x02-0x3e: Reserved */
935 			break;
936 		}
937 		break;
938 	case 0x0b:
939 		/* Obsolete (Medium Types Supported) */
940 		break;
941 	case 0x0c:
942 		/* Obsolete (Notch And Partitio) */
943 		break;
944 	case 0x0d:
945 		/* Obsolete */
946 		break;
947 	case 0x0e:
948 	case 0x0f:
949 		/* Reserved */
950 		break;
951 	case 0x10:
952 		/* XOR Control */
953 		SPDK_TRACELOG(SPDK_TRACE_SCSI, "MODE_SENSE XOR Control\n");
954 		if (subpage != 0x00)
955 			break;
956 		plen = 0x16 + 2;
957 		mode_sense_page_init(cp, plen, page, subpage);
958 		len += plen;
959 		break;
960 	case 0x11:
961 	case 0x12:
962 	case 0x13:
963 		/* Reserved */
964 		break;
965 	case 0x14:
966 		/* Enclosure Services Management */
967 		break;
968 	case 0x15:
969 	case 0x16:
970 	case 0x17:
971 		/* Reserved */
972 		break;
973 	case 0x18:
974 		/* Protocol-Specific LUN */
975 		break;
976 	case 0x19:
977 		/* Protocol-Specific Port */
978 		break;
979 	case 0x1a:
980 		/* Power Condition */
981 		SPDK_TRACELOG(SPDK_TRACE_SCSI,
982 			      "MODE_SENSE Power Condition\n");
983 		if (subpage != 0x00)
984 			break;
985 		plen = 0x0a + 2;
986 		mode_sense_page_init(cp, plen, page, subpage);
987 		len += plen;
988 		break;
989 	case 0x1b:
990 		/* Reserved */
991 		break;
992 	case 0x1c:
993 		/* Informational Exceptions Control */
994 		SPDK_TRACELOG(SPDK_TRACE_SCSI,
995 			      "MODE_SENSE Informational Exceptions Control\n");
996 		if (subpage != 0x00)
997 			break;
998 
999 		plen = 0x0a + 2;
1000 		mode_sense_page_init(cp, plen, page, subpage);
1001 		len += plen;
1002 		break;
1003 	case 0x1d:
1004 	case 0x1e:
1005 	case 0x1f:
1006 		/* Reserved */
1007 		break;
1008 	case 0x20:
1009 	case 0x21:
1010 	case 0x22:
1011 	case 0x23:
1012 	case 0x24:
1013 	case 0x25:
1014 	case 0x26:
1015 	case 0x27:
1016 	case 0x28:
1017 	case 0x29:
1018 	case 0x2a:
1019 	case 0x2b:
1020 	case 0x2c:
1021 	case 0x2d:
1022 	case 0x2e:
1023 	case 0x2f:
1024 	case 0x30:
1025 	case 0x31:
1026 	case 0x32:
1027 	case 0x33:
1028 	case 0x34:
1029 	case 0x35:
1030 	case 0x36:
1031 	case 0x37:
1032 	case 0x38:
1033 	case 0x39:
1034 	case 0x3a:
1035 	case 0x3b:
1036 	case 0x3c:
1037 	case 0x3d:
1038 	case 0x3e:
1039 		/* Vendor-specific */
1040 		break;
1041 	case 0x3f:
1042 		switch (subpage) {
1043 		case 0x00:
1044 			/* All mode pages */
1045 			for (i = 0x00; i < 0x3e; i ++) {
1046 				len += spdk_bdev_scsi_mode_sense_page(
1047 					       bdev, cdb, pc, i, 0x00,
1048 					       cp ? &cp[len] : NULL, task);
1049 			}
1050 			break;
1051 		case 0xff:
1052 			/* All mode pages and subpages */
1053 			for (i = 0x00; i < 0x3e; i ++) {
1054 				len += spdk_bdev_scsi_mode_sense_page(
1055 					       bdev, cdb, pc, i, 0x00,
1056 					       cp ? &cp[len] : NULL, task);
1057 			}
1058 			for (i = 0x00; i < 0x3e; i ++) {
1059 				len += spdk_bdev_scsi_mode_sense_page(
1060 					       bdev, cdb, pc, i, 0xff,
1061 					       cp ? &cp[len] : NULL, task);
1062 			}
1063 			break;
1064 		default:
1065 			/* 0x01-0x3e: Reserved */
1066 			break;
1067 		}
1068 	}
1069 
1070 	return len;
1071 }
1072 
1073 static int
1074 spdk_bdev_scsi_mode_sense(struct spdk_bdev *bdev, int md,
1075 			  uint8_t *cdb, int dbd, int llbaa, int pc,
1076 			  int page, int subpage, uint8_t *data, struct spdk_scsi_task *task)
1077 {
1078 	uint64_t num_blocks = spdk_bdev_get_num_blocks(bdev);
1079 	uint32_t block_size = spdk_bdev_get_block_size(bdev);
1080 	uint8_t *hdr, *bdesc, *pages;
1081 	int hlen;
1082 	int blen;
1083 	int plen, total;
1084 
1085 	assert(md == 6 || md == 10);
1086 
1087 	if (md == 6) {
1088 		hlen = 4;
1089 		blen = 8; /* For MODE SENSE 6 only short LBA */
1090 	} else {
1091 		hlen = 8;
1092 		blen = llbaa ? 16 : 8;
1093 	}
1094 
1095 	if (dbd) {
1096 		blen = 0;
1097 	}
1098 
1099 	pages = data ? &data[hlen + blen] : NULL;
1100 	plen = spdk_bdev_scsi_mode_sense_page(bdev, cdb, pc, page,
1101 					      subpage,
1102 					      pages, task);
1103 	if (plen < 0) {
1104 		return -1;
1105 	}
1106 
1107 	total = hlen + blen + plen;
1108 	if (data == NULL)
1109 		return total;
1110 
1111 	hdr = &data[0];
1112 	if (hlen == 4) {
1113 		hdr[0] = total - 1;            /* Mode Data Length */
1114 		hdr[1] = 0;                    /* Medium Type */
1115 		hdr[2] = 0;                    /* Device-Specific Parameter */
1116 		hdr[3] = blen;                 /* Block Descripter Length */
1117 	} else {
1118 		to_be16(&hdr[0], total - 2);   /* Mode Data Length */
1119 		hdr[2] = 0;                    /* Medium Type */
1120 		hdr[3] = 0;                    /* Device-Specific Parameter */
1121 		hdr[4] = llbaa ? 0x1 : 0;      /* Long/short LBA */
1122 		hdr[5] = 0;                    /* Reserved */
1123 		to_be16(&hdr[6], blen);        /* Block Descripter Length */
1124 	}
1125 
1126 	bdesc = &data[hlen];
1127 	if (blen == 16) {
1128 		/* Number of Blocks */
1129 		to_be64(&bdesc[0], num_blocks);
1130 		/* Reserved */
1131 		memset(&bdesc[8], 0, 4);
1132 		/* Block Length */
1133 		to_be32(&bdesc[12], block_size);
1134 	} else if (blen == 8) {
1135 		/* Number of Blocks */
1136 		if (num_blocks > 0xffffffffULL)
1137 			memset(&bdesc[0], 0xff, 4);
1138 		else
1139 			to_be32(&bdesc[0], num_blocks);
1140 
1141 		/* Block Length */
1142 		to_be32(&bdesc[4], block_size);
1143 	}
1144 
1145 	return total;
1146 }
1147 
1148 static int
1149 spdk_bdev_scsi_mode_select_page(struct spdk_bdev *bdev,
1150 				uint8_t *cdb, int pf, int sp,
1151 				uint8_t *data, size_t len)
1152 {
1153 	size_t hlen, plen;
1154 	int spf, page, subpage;
1155 	int rc;
1156 
1157 	/* vendor specific */
1158 	if (pf == 0) {
1159 		return 0;
1160 	}
1161 
1162 	if (len < 1) {
1163 		return 0;
1164 	}
1165 
1166 	spf = !!(data[0] & 0x40);
1167 	page = data[0] & 0x3f;
1168 	if (spf) {
1169 		/* Sub_page mode page format */
1170 		hlen = 4;
1171 		if (len < hlen)
1172 			return 0;
1173 		subpage = data[1];
1174 
1175 		plen = from_be16(&data[2]);
1176 	} else {
1177 		/* Page_0 mode page format */
1178 		hlen = 2;
1179 		if (len < hlen)
1180 			return 0;
1181 		subpage = 0;
1182 		plen = data[1];
1183 	}
1184 
1185 	plen += hlen;
1186 	if (len < plen) {
1187 		return 0;
1188 	}
1189 
1190 	switch (page) {
1191 	case 0x08: { /* Caching */
1192 		//int wce;
1193 
1194 		SPDK_TRACELOG(SPDK_TRACE_SCSI, "MODE_SELECT Caching\n");
1195 		if (subpage != 0x00)
1196 			break;
1197 
1198 		if (plen != 0x12 + hlen) {
1199 			/* unknown format */
1200 			break;
1201 		}
1202 
1203 		// TODO:
1204 		//wce = data[2] & 0x4; /* WCE */
1205 
1206 		//fd = bdev->fd;
1207 		//
1208 		//rc = fcntl(fd, F_GETFL, 0);
1209 		//if (rc != -1) {
1210 		//	if (wce) {
1211 		//		SPDK_TRACELOG(SPDK_TRACE_SCSI, "MODE_SELECT Writeback cache enable\n");
1212 		//		rc = fcntl(fd, F_SETFL, (rc & ~O_FSYNC));
1213 		//		bdev->write_cache = 1;
1214 		//	} else {
1215 		//		rc = fcntl(fd, F_SETFL, (rc | O_FSYNC));
1216 		//		bdev->write_cache = 0;
1217 		//	}
1218 		//}
1219 
1220 		break;
1221 	}
1222 	default:
1223 		/* not supported */
1224 		break;
1225 	}
1226 
1227 	len -= plen;
1228 	if (len != 0) {
1229 		rc = spdk_bdev_scsi_mode_select_page(bdev, cdb, pf, sp, &data[plen], len);
1230 		if (rc < 0) {
1231 			return rc;
1232 		}
1233 	}
1234 	return 0;
1235 }
1236 
1237 static void
1238 spdk_bdev_scsi_task_complete_cmd(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status,
1239 				 void *cb_arg)
1240 {
1241 	struct spdk_scsi_task *task = cb_arg;
1242 	int sc, sk, asc, ascq;
1243 
1244 	spdk_bdev_io_get_scsi_status(bdev_io, &sc, &sk, &asc, &ascq);
1245 	spdk_scsi_task_set_status(task, sc, sk, asc, ascq);
1246 	spdk_scsi_lun_complete_task(task->lun, task);
1247 }
1248 
1249 static void
1250 spdk_bdev_scsi_task_complete_mgmt(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status,
1251 				  void *cb_arg)
1252 {
1253 	struct spdk_scsi_task *task = cb_arg;
1254 
1255 	if (status == SPDK_BDEV_IO_STATUS_SUCCESS) {
1256 		task->response = SPDK_SCSI_TASK_MGMT_RESP_SUCCESS;
1257 	}
1258 
1259 	spdk_scsi_lun_complete_mgmt_task(task->lun, task);
1260 }
1261 
1262 static int
1263 spdk_bdev_scsi_read_write_lba_check(struct spdk_scsi_task *primary,
1264 				    struct spdk_scsi_task *task,
1265 				    uint64_t lba, uint64_t cmd_num_blocks,
1266 				    uint64_t bdev_num_blocks)
1267 {
1268 	if (!primary) {
1269 		/*
1270 		 * Indicates this task is a primary task, we check whether the LBA and
1271 		 * range is valid. If such info of primary is valid, all subtasks' are valid.
1272 		 */
1273 		if (lba >= bdev_num_blocks || cmd_num_blocks > bdev_num_blocks ||
1274 		    lba > (bdev_num_blocks - cmd_num_blocks)) {
1275 			SPDK_TRACELOG(SPDK_TRACE_SCSI, "end of media\n");
1276 			spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1277 						  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
1278 						  SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1279 						  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1280 			return -1;
1281 		}
1282 	} else {
1283 		/*
1284 		 * Indicates this task is a subtask, we do not need to check the LBA range.
1285 		 * Need to check condition of primary task.
1286 		 */
1287 		if (primary->status == SPDK_SCSI_STATUS_CHECK_CONDITION) {
1288 			memcpy(task->sense_data, primary->sense_data,
1289 			       primary->sense_data_len);
1290 			task->status = SPDK_SCSI_STATUS_CHECK_CONDITION;
1291 			task->sense_data_len = primary->sense_data_len;
1292 			return -1;
1293 		}
1294 	}
1295 
1296 	return 0;
1297 }
1298 
1299 static int
1300 spdk_bdev_scsi_read(struct spdk_bdev *bdev,
1301 		    struct spdk_scsi_task *task, uint64_t lba,
1302 		    uint32_t len)
1303 {
1304 	uint64_t blen;
1305 	uint64_t offset;
1306 	uint64_t nbytes;
1307 
1308 	blen = spdk_bdev_get_block_size(bdev);
1309 
1310 	lba += (task->offset / blen);
1311 	offset = lba * blen;
1312 	nbytes = task->length;
1313 
1314 	SPDK_TRACELOG(SPDK_TRACE_SCSI,
1315 		      "Read: lba=%"PRIu64", len=%"PRIu64"\n",
1316 		      lba, (uint64_t)task->length / blen);
1317 
1318 	task->blockdev_io = spdk_bdev_readv(bdev, task->ch, task->iovs,
1319 					    task->iovcnt, offset, nbytes,
1320 					    spdk_bdev_scsi_task_complete_cmd, task);
1321 	if (!task->blockdev_io) {
1322 		SPDK_ERRLOG("spdk_bdev_readv() failed\n");
1323 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1324 					  SPDK_SCSI_SENSE_NO_SENSE,
1325 					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1326 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1327 		return SPDK_SCSI_TASK_COMPLETE;
1328 	}
1329 
1330 	task->data_transferred = nbytes;
1331 	task->status = SPDK_SCSI_STATUS_GOOD;
1332 
1333 	return SPDK_SCSI_TASK_PENDING;
1334 }
1335 
1336 static int
1337 spdk_bdev_scsi_write(struct spdk_bdev *bdev,
1338 		     struct spdk_scsi_task *task, uint64_t lba, uint32_t len)
1339 {
1340 	uint64_t blen;
1341 	uint64_t offset;
1342 	uint64_t nbytes;
1343 	struct spdk_scsi_task *primary = task->parent;
1344 
1345 	if (len == 0) {
1346 		task->data_transferred = 0;
1347 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1348 					  SPDK_SCSI_SENSE_NO_SENSE,
1349 					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1350 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1351 		return SPDK_SCSI_TASK_COMPLETE;
1352 	}
1353 
1354 	blen = spdk_bdev_get_block_size(bdev);
1355 	offset = lba * blen;
1356 	nbytes = ((uint64_t)len) * blen;
1357 
1358 	SPDK_TRACELOG(SPDK_TRACE_SCSI,
1359 		      "Write: lba=%"PRIu64", len=%u\n",
1360 		      lba, len);
1361 
1362 	if (nbytes > task->transfer_len) {
1363 		SPDK_ERRLOG("nbytes(%zu) > transfer_len(%u)\n",
1364 			    (size_t)nbytes, task->transfer_len);
1365 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1366 					  SPDK_SCSI_SENSE_NO_SENSE,
1367 					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1368 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1369 		return SPDK_SCSI_TASK_COMPLETE;
1370 	}
1371 
1372 	offset += task->offset;
1373 	task->blockdev_io = spdk_bdev_writev(bdev, task->ch, task->iovs,
1374 					     task->iovcnt, offset, task->length,
1375 					     spdk_bdev_scsi_task_complete_cmd,
1376 					     task);
1377 
1378 	if (!task->blockdev_io) {
1379 		SPDK_ERRLOG("spdk_bdev_writev failed\n");
1380 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1381 					  SPDK_SCSI_SENSE_NO_SENSE,
1382 					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1383 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1384 		return SPDK_SCSI_TASK_COMPLETE;
1385 	} else {
1386 		if (!primary) {
1387 			task->data_transferred += task->length;
1388 		} else {
1389 			primary->data_transferred += task->length;
1390 		}
1391 	}
1392 
1393 	SPDK_TRACELOG(SPDK_TRACE_SCSI, "Wrote %"PRIu64"/%"PRIu64" bytes\n",
1394 		      (uint64_t)task->length, nbytes);
1395 
1396 	task->status = SPDK_SCSI_STATUS_GOOD;
1397 	return SPDK_SCSI_TASK_PENDING;
1398 }
1399 
1400 static int
1401 spdk_bdev_scsi_sync(struct spdk_bdev *bdev, struct spdk_scsi_task *task,
1402 		    uint64_t lba, uint32_t num_blocks)
1403 {
1404 	uint64_t bdev_num_blocks;
1405 	uint64_t blen;
1406 	uint64_t offset;
1407 	uint64_t nbytes;
1408 
1409 	if (num_blocks == 0) {
1410 		return SPDK_SCSI_TASK_COMPLETE;
1411 	}
1412 
1413 	bdev_num_blocks = spdk_bdev_get_num_blocks(bdev);
1414 	blen = spdk_bdev_get_block_size(bdev);
1415 	offset = lba * blen;
1416 	nbytes = num_blocks * blen;
1417 
1418 	if (lba >= bdev_num_blocks || num_blocks > bdev_num_blocks ||
1419 	    lba > (bdev_num_blocks - num_blocks)) {
1420 		SPDK_ERRLOG("end of media\n");
1421 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1422 					  SPDK_SCSI_SENSE_NO_SENSE,
1423 					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1424 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1425 		return SPDK_SCSI_TASK_COMPLETE;
1426 	}
1427 
1428 	task->blockdev_io = spdk_bdev_flush(bdev, task->ch, offset, nbytes,
1429 					    spdk_bdev_scsi_task_complete_cmd, task);
1430 
1431 	if (!task->blockdev_io) {
1432 		SPDK_ERRLOG("spdk_bdev_flush() failed\n");
1433 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1434 					  SPDK_SCSI_SENSE_NO_SENSE,
1435 					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1436 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1437 		return SPDK_SCSI_TASK_COMPLETE;
1438 	}
1439 	task->data_transferred = 0;
1440 	task->status = SPDK_SCSI_STATUS_GOOD;
1441 	return SPDK_SCSI_TASK_PENDING;
1442 }
1443 
1444 static int
1445 spdk_bdev_scsi_readwrite(struct spdk_bdev *bdev,
1446 			 struct spdk_scsi_task *task,
1447 			 uint64_t lba, uint32_t xfer_len, bool is_read)
1448 {
1449 	if (task->dxfer_dir != SPDK_SCSI_DIR_NONE &&
1450 	    task->dxfer_dir != (is_read ? SPDK_SCSI_DIR_FROM_DEV : SPDK_SCSI_DIR_TO_DEV)) {
1451 		SPDK_ERRLOG("Incorrect data direction\n");
1452 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1453 					  SPDK_SCSI_SENSE_NO_SENSE,
1454 					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1455 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1456 		return SPDK_SCSI_TASK_COMPLETE;
1457 	}
1458 
1459 	if (spdk_bdev_scsi_read_write_lba_check(task->parent, task, lba,
1460 						xfer_len, spdk_bdev_get_num_blocks(bdev)) < 0) {
1461 		/* spdk_bdev_scsi_read_write_lba_check() already set the correct sense code */
1462 		return SPDK_SCSI_TASK_COMPLETE;
1463 	}
1464 
1465 	if (is_read) {
1466 		return spdk_bdev_scsi_read(bdev, task, lba, xfer_len);
1467 	} else {
1468 		return spdk_bdev_scsi_write(bdev, task, lba, xfer_len);
1469 	}
1470 }
1471 
1472 static int
1473 spdk_bdev_scsi_unmap(struct spdk_bdev *bdev,
1474 		     struct spdk_scsi_task *task)
1475 {
1476 
1477 	uint8_t *data;
1478 	struct spdk_scsi_unmap_bdesc *desc;
1479 	uint32_t bdesc_count, max_unmap_bdesc_count;
1480 	int bdesc_data_len;
1481 	int data_len;
1482 
1483 	if (task->iovcnt == 1) {
1484 		data = (uint8_t *)task->iovs[0].iov_base;
1485 		data_len = task->iovs[0].iov_len;
1486 	} else {
1487 		data = spdk_scsi_task_gather_data(task, &data_len);
1488 	}
1489 
1490 	/*
1491 	 * The UNMAP BLOCK DESCRIPTOR DATA LENGTH field specifies the length in
1492 	 * bytes of the UNMAP block descriptors that are available to be
1493 	 * transferred from the Data-Out Buffer. The unmap block descriptor data
1494 	 * length should be a multiple of 16. If the unmap block descriptor data
1495 	 * length is not a multiple of 16, then the last unmap block descriptor
1496 	 * is incomplete and shall be ignored.
1497 	 */
1498 	bdesc_data_len = from_be16(&data[2]);
1499 	bdesc_count = bdesc_data_len / 16;
1500 	assert(bdesc_data_len <= data_len);
1501 
1502 	if (task->iovcnt == 1) {
1503 		desc = (struct spdk_scsi_unmap_bdesc *)&data[8];
1504 	} else {
1505 		desc = spdk_scsi_task_alloc_data(task, bdesc_data_len - 8);
1506 		memcpy(desc, &data[8], bdesc_data_len - 8);
1507 		spdk_free(data);
1508 	}
1509 
1510 	max_unmap_bdesc_count = spdk_bdev_get_max_unmap_descriptors(bdev);
1511 	if (bdesc_count > max_unmap_bdesc_count) {
1512 		SPDK_ERRLOG("Error - supported unmap block descriptor count limit"
1513 			    " is %u\n", max_unmap_bdesc_count);
1514 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1515 					  SPDK_SCSI_SENSE_NO_SENSE,
1516 					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1517 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1518 		return SPDK_SCSI_TASK_COMPLETE;
1519 	} else if (bdesc_data_len > data_len) {
1520 		SPDK_ERRLOG("Error - bdesc_data_len (%d) > data_len (%d)",
1521 			    bdesc_data_len, data_len);
1522 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1523 					  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
1524 					  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
1525 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1526 		return SPDK_SCSI_TASK_COMPLETE;
1527 	}
1528 
1529 	task->blockdev_io = spdk_bdev_unmap(bdev, task->ch, desc,
1530 					    bdesc_count, spdk_bdev_scsi_task_complete_cmd,
1531 					    task);
1532 
1533 	if (!task->blockdev_io) {
1534 		SPDK_ERRLOG("SCSI Unmapping failed\n");
1535 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1536 					  SPDK_SCSI_SENSE_NO_SENSE,
1537 					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1538 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1539 		return SPDK_SCSI_TASK_COMPLETE;
1540 	}
1541 
1542 	return SPDK_SCSI_TASK_PENDING;
1543 }
1544 
1545 static int
1546 spdk_bdev_scsi_process_block(struct spdk_bdev *bdev,
1547 			     struct spdk_scsi_task *task)
1548 {
1549 	uint64_t lba;
1550 	uint32_t xfer_len;
1551 	uint32_t len = 0;
1552 	uint8_t *cdb = task->cdb;
1553 
1554 	/* XXX: We need to support FUA bit for writes! */
1555 	switch (cdb[0]) {
1556 	case SPDK_SBC_READ_6:
1557 	case SPDK_SBC_WRITE_6:
1558 		lba = (uint64_t)cdb[1] << 16;
1559 		lba |= (uint64_t)cdb[2] << 8;
1560 		lba |= (uint64_t)cdb[3];
1561 		xfer_len = cdb[4];
1562 		if (xfer_len == 0) {
1563 			xfer_len = 256;
1564 		}
1565 		return spdk_bdev_scsi_readwrite(bdev, task, lba, xfer_len,
1566 						cdb[0] == SPDK_SBC_READ_6);
1567 
1568 	case SPDK_SBC_READ_10:
1569 	case SPDK_SBC_WRITE_10:
1570 		lba = from_be32(&cdb[2]);
1571 		xfer_len = from_be16(&cdb[7]);
1572 		return spdk_bdev_scsi_readwrite(bdev, task, lba, xfer_len,
1573 						cdb[0] == SPDK_SBC_READ_10);
1574 
1575 	case SPDK_SBC_READ_12:
1576 	case SPDK_SBC_WRITE_12:
1577 		lba = from_be32(&cdb[2]);
1578 		xfer_len = from_be32(&cdb[6]);
1579 		return spdk_bdev_scsi_readwrite(bdev, task, lba, xfer_len,
1580 						cdb[0] == SPDK_SBC_READ_12);
1581 	case SPDK_SBC_READ_16:
1582 	case SPDK_SBC_WRITE_16:
1583 		lba = from_be64(&cdb[2]);
1584 		xfer_len = from_be32(&cdb[10]);
1585 		return spdk_bdev_scsi_readwrite(bdev, task, lba, xfer_len,
1586 						cdb[0] == SPDK_SBC_READ_16);
1587 
1588 	case SPDK_SBC_READ_CAPACITY_10: {
1589 		uint64_t num_blocks = spdk_bdev_get_num_blocks(bdev);
1590 		uint8_t buffer[8];
1591 
1592 		if (num_blocks - 1 > 0xffffffffULL) {
1593 			memset(buffer, 0xff, 4);
1594 		} else {
1595 			to_be32(buffer, num_blocks - 1);
1596 		}
1597 		to_be32(&buffer[4], spdk_bdev_get_block_size(bdev));
1598 
1599 		len = spdk_min(task->length, sizeof(buffer));
1600 		if (spdk_scsi_task_scatter_data(task, buffer, len) < 0)
1601 			break;
1602 
1603 		task->data_transferred = len;
1604 		task->status = SPDK_SCSI_STATUS_GOOD;
1605 		break;
1606 	}
1607 
1608 	case SPDK_SPC_SERVICE_ACTION_IN_16:
1609 		switch (cdb[1] & 0x1f) { /* SERVICE ACTION */
1610 		case SPDK_SBC_SAI_READ_CAPACITY_16: {
1611 			uint8_t buffer[32] = {0};
1612 
1613 			to_be64(&buffer[0], spdk_bdev_get_num_blocks(bdev) - 1);
1614 			to_be32(&buffer[8], spdk_bdev_get_block_size(bdev));
1615 			/*
1616 			 * Set the TPE bit to 1 to indicate thin provisioning.
1617 			 * The position of TPE bit is the 7th bit in 14th byte
1618 			 * in READ CAPACITY (16) parameter data.
1619 			 */
1620 			if (spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_UNMAP)) {
1621 				buffer[14] |= 1 << 7;
1622 			}
1623 
1624 			len = spdk_min(from_be32(&cdb[10]), sizeof(buffer));
1625 			if (spdk_scsi_task_scatter_data(task, buffer, len) < 0)
1626 				break;
1627 
1628 			task->data_transferred = len;
1629 			task->status = SPDK_SCSI_STATUS_GOOD;
1630 			break;
1631 		}
1632 
1633 		default:
1634 			return SPDK_SCSI_TASK_UNKNOWN;
1635 		}
1636 		break;
1637 
1638 	case SPDK_SBC_SYNCHRONIZE_CACHE_10:
1639 	case SPDK_SBC_SYNCHRONIZE_CACHE_16:
1640 		if (cdb[0] == SPDK_SBC_SYNCHRONIZE_CACHE_10) {
1641 			lba = from_be32(&cdb[2]);
1642 			len = from_be16(&cdb[7]);
1643 		} else {
1644 			lba = from_be64(&cdb[2]);
1645 			len = from_be32(&cdb[10]);
1646 		}
1647 
1648 		if (len == 0) {
1649 			len = spdk_bdev_get_num_blocks(bdev) - lba;
1650 		}
1651 
1652 		return spdk_bdev_scsi_sync(bdev, task, lba, len);
1653 		break;
1654 
1655 	case SPDK_SBC_UNMAP:
1656 		return spdk_bdev_scsi_unmap(bdev, task);
1657 
1658 	default:
1659 		return SPDK_SCSI_TASK_UNKNOWN;
1660 	}
1661 
1662 	return SPDK_SCSI_TASK_COMPLETE;
1663 }
1664 
1665 static int
1666 spdk_bdev_scsi_check_len(struct spdk_scsi_task *task, int len, int min_len)
1667 {
1668 	if (len >= min_len)
1669 		return 0;
1670 
1671 	/* INVALID FIELD IN CDB */
1672 	spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1673 				  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
1674 				  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
1675 				  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1676 	return -1;
1677 }
1678 
1679 static int
1680 spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
1681 			       struct spdk_scsi_task *task)
1682 {
1683 	int alloc_len = -1;
1684 	int data_len = -1;
1685 	uint8_t *cdb = task->cdb;
1686 	uint8_t *data = NULL;
1687 	int rc = 0;
1688 	int pllen, md = 0;
1689 	int pf, sp;
1690 	int bdlen, llba;
1691 	int dbd, pc, page, subpage;
1692 	int cmd_parsed = 0;
1693 
1694 
1695 	switch (cdb[0]) {
1696 	case SPDK_SPC_INQUIRY:
1697 		alloc_len = from_be16(&cdb[3]);
1698 		data_len = spdk_max(4096, alloc_len);
1699 		data = spdk_zmalloc(data_len, 0, NULL);
1700 		assert(data != NULL);
1701 		rc = spdk_bdev_scsi_inquiry(bdev, task, cdb, data, data_len);
1702 		data_len = spdk_min(rc, data_len);
1703 		if (rc < 0) {
1704 			break;
1705 		}
1706 
1707 		SPDK_TRACEDUMP(SPDK_TRACE_DEBUG, "INQUIRY", data, data_len);
1708 		break;
1709 
1710 	case SPDK_SPC_REPORT_LUNS: {
1711 		int sel;
1712 
1713 		sel = cdb[2];
1714 		SPDK_TRACELOG(SPDK_TRACE_DEBUG, "sel=%x\n", sel);
1715 
1716 		alloc_len = from_be32(&cdb[6]);
1717 		rc = spdk_bdev_scsi_check_len(task, alloc_len, 16);
1718 		if (rc < 0) {
1719 			break;
1720 		}
1721 
1722 		data_len = spdk_max(4096, alloc_len);
1723 		data = spdk_zmalloc(data_len, 0, NULL);
1724 		assert(data != NULL);
1725 		rc = spdk_bdev_scsi_report_luns(task->lun, sel, data, data_len);
1726 		data_len = rc;
1727 		if (rc < 0) {
1728 			spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1729 						  SPDK_SCSI_SENSE_NO_SENSE,
1730 						  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1731 						  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1732 			break;
1733 		}
1734 
1735 		SPDK_TRACEDUMP(SPDK_TRACE_DEBUG, "REPORT LUNS", data, data_len);
1736 		break;
1737 	}
1738 
1739 	case SPDK_SPC_MODE_SELECT_6:
1740 	case SPDK_SPC_MODE_SELECT_10:
1741 		if (cdb[0] == SPDK_SPC_MODE_SELECT_6) {
1742 			/* MODE_SELECT(6) must have at least a 4 byte header. */
1743 			md = 4;
1744 			pllen = cdb[4];
1745 		} else {
1746 			/* MODE_SELECT(10) must have at least an 8 byte header. */
1747 			md = 8;
1748 			pllen = from_be16(&cdb[7]);
1749 		}
1750 
1751 		if (pllen == 0) {
1752 			break;
1753 		}
1754 
1755 		rc = spdk_bdev_scsi_check_len(task, pllen, md);
1756 		if (rc < 0) {
1757 			break;
1758 		}
1759 
1760 		data = spdk_scsi_task_gather_data(task, &rc);
1761 		if (rc < 0) {
1762 			break;
1763 		}
1764 
1765 		data_len = rc;
1766 		if (cdb[0] == SPDK_SPC_MODE_SELECT_6) {
1767 			rc = spdk_bdev_scsi_check_len(task, data_len, 4);
1768 			if (rc >= 0) {
1769 				bdlen = data[3];
1770 			}
1771 
1772 		} else {
1773 			rc = spdk_bdev_scsi_check_len(task, data_len, 8);
1774 			if (rc >= 0) {
1775 				bdlen = from_be16(&data[6]);
1776 			}
1777 		}
1778 
1779 		if (rc < 0) {
1780 			break;
1781 		}
1782 		pf = !!(cdb[1] & 0x10);
1783 		sp = !!(cdb[1] & 0x1);
1784 
1785 		/* page data */
1786 		rc = spdk_bdev_scsi_mode_select_page(
1787 			     bdev, cdb,
1788 			     pf, sp,
1789 			     &data[md + bdlen],
1790 			     pllen - (md + bdlen));
1791 		if (rc < 0) {
1792 			spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1793 						  SPDK_SCSI_SENSE_NO_SENSE,
1794 						  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1795 						  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1796 			break;
1797 		}
1798 
1799 		rc = pllen;
1800 		data_len = 0;
1801 		break;
1802 
1803 	case SPDK_SPC_MODE_SENSE_6:
1804 		alloc_len = cdb[4];
1805 		md = 6;
1806 
1807 	case SPDK_SPC_MODE_SENSE_10:
1808 		llba = 0;
1809 
1810 		if (md == 0) {
1811 			alloc_len = from_be16(&cdb[7]);
1812 			llba = !!(cdb[1] & 0x10);
1813 			md = 10;
1814 		}
1815 
1816 		dbd = !!(cdb[1] & 0x8);
1817 		pc = (cdb[2] & 0xc0) >> 6;
1818 		page = cdb[2] & 0x3f;
1819 		subpage = cdb[3];
1820 
1821 		/* First call with no buffer to discover needed buffer size */
1822 		rc = spdk_bdev_scsi_mode_sense(bdev, md,
1823 					       cdb, dbd, llba, pc,
1824 					       page, subpage,
1825 					       NULL, task);
1826 		if (rc < 0) {
1827 			break;
1828 		}
1829 
1830 		data_len = rc;
1831 		data = spdk_zmalloc(data_len, 0, NULL);
1832 		assert(data != NULL);
1833 
1834 		/* First call with no buffer to discover needed buffer size */
1835 		rc = spdk_bdev_scsi_mode_sense(bdev, md,
1836 					       cdb, dbd, llba, pc,
1837 					       page, subpage,
1838 					       data, task);
1839 		if (rc < 0) {
1840 			/* INVALID FIELD IN CDB */
1841 			spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1842 						  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
1843 						  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
1844 						  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1845 			break;
1846 		}
1847 		break;
1848 
1849 	case SPDK_SPC_REQUEST_SENSE: {
1850 		int desc;
1851 		int sk, asc, ascq;
1852 
1853 		desc = cdb[1] & 0x1;
1854 		if (desc != 0) {
1855 			/* INVALID FIELD IN CDB */
1856 			spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1857 						  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
1858 						  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
1859 						  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1860 			break;
1861 		}
1862 
1863 		alloc_len = cdb[4];
1864 
1865 		/* NO ADDITIONAL SENSE INFORMATION */
1866 		sk = SPDK_SCSI_SENSE_NO_SENSE;
1867 		asc = 0x00;
1868 		ascq = 0x00;
1869 
1870 		spdk_scsi_task_build_sense_data(task, sk, asc, ascq);
1871 
1872 		data_len = task->sense_data_len;
1873 		data = spdk_zmalloc(data_len, 0, NULL);
1874 		assert(data != NULL);
1875 		memcpy(data, task->sense_data, data_len);
1876 		break;
1877 	}
1878 
1879 	case SPDK_SPC_LOG_SELECT:
1880 		SPDK_TRACELOG(SPDK_TRACE_SCSI, "LOG_SELECT\n");
1881 		cmd_parsed = 1;
1882 	case SPDK_SPC_LOG_SENSE:
1883 		if (!cmd_parsed) {
1884 			SPDK_TRACELOG(SPDK_TRACE_SCSI, "LOG_SENSE\n");
1885 		}
1886 
1887 		/* INVALID COMMAND OPERATION CODE */
1888 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1889 					  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
1890 					  SPDK_SCSI_ASC_INVALID_COMMAND_OPERATION_CODE,
1891 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1892 		rc = -1;
1893 		break;
1894 
1895 	case SPDK_SPC_TEST_UNIT_READY:
1896 		SPDK_TRACELOG(SPDK_TRACE_SCSI, "TEST_UNIT_READY\n");
1897 		cmd_parsed = 1;
1898 	case SPDK_SBC_START_STOP_UNIT:
1899 		if (!cmd_parsed) {
1900 			SPDK_TRACELOG(SPDK_TRACE_SCSI, "START_STOP_UNIT\n");
1901 		}
1902 
1903 		rc = 0;
1904 		break;
1905 
1906 	default:
1907 		return SPDK_SCSI_TASK_UNKNOWN;
1908 	}
1909 
1910 	if (rc >= 0 && data_len > 0) {
1911 		assert(alloc_len >= 0);
1912 		spdk_scsi_task_scatter_data(task, data, spdk_min(alloc_len, data_len));
1913 		rc = spdk_min(data_len, alloc_len);
1914 	}
1915 
1916 	if (rc >= 0) {
1917 		task->data_transferred = rc;
1918 		task->status = SPDK_SCSI_STATUS_GOOD;
1919 	}
1920 
1921 	if (data)
1922 		spdk_free(data);
1923 
1924 	return SPDK_SCSI_TASK_COMPLETE;
1925 }
1926 
1927 int
1928 spdk_bdev_scsi_execute(struct spdk_bdev *bdev, struct spdk_scsi_task *task)
1929 {
1930 	int rc;
1931 
1932 	if ((rc = spdk_bdev_scsi_process_block(bdev, task)) == SPDK_SCSI_TASK_UNKNOWN) {
1933 		if ((rc = spdk_bdev_scsi_process_primary(bdev, task)) == SPDK_SCSI_TASK_UNKNOWN) {
1934 			SPDK_TRACELOG(SPDK_TRACE_SCSI, "unsupported SCSI OP=0x%x\n", task->cdb[0]);
1935 			/* INVALID COMMAND OPERATION CODE */
1936 			spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1937 						  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
1938 						  SPDK_SCSI_ASC_INVALID_COMMAND_OPERATION_CODE,
1939 						  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1940 			return SPDK_SCSI_TASK_COMPLETE;
1941 		}
1942 	}
1943 
1944 	return rc;
1945 }
1946 
1947 int
1948 spdk_bdev_scsi_reset(struct spdk_bdev *bdev, struct spdk_scsi_task *task)
1949 {
1950 	return spdk_bdev_reset(bdev, SPDK_BDEV_RESET_SOFT,
1951 			       spdk_bdev_scsi_task_complete_mgmt, task);
1952 }
1953