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