xref: /spdk/lib/vhost/vhost_scsi.c (revision 927f1fd57bd004df581518466ec4c1b8083e5d23)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/stdinc.h"
35 
36 #include <linux/virtio_scsi.h>
37 
38 #include "spdk/env.h"
39 #include "spdk/thread.h"
40 #include "spdk/scsi.h"
41 #include "spdk/scsi_spec.h"
42 #include "spdk/util.h"
43 #include "spdk/likely.h"
44 
45 #include "spdk/vhost.h"
46 #include "vhost_internal.h"
47 
48 /* Features supported by SPDK VHOST lib. */
49 #define SPDK_VHOST_SCSI_FEATURES	(SPDK_VHOST_FEATURES | \
50 					(1ULL << VIRTIO_SCSI_F_INOUT) | \
51 					(1ULL << VIRTIO_SCSI_F_HOTPLUG) | \
52 					(1ULL << VIRTIO_SCSI_F_CHANGE ) | \
53 					(1ULL << VIRTIO_SCSI_F_T10_PI ))
54 
55 /* Features that are specified in VIRTIO SCSI but currently not supported:
56  * - Live migration not supported yet
57  * - T10 PI
58  */
59 #define SPDK_VHOST_SCSI_DISABLED_FEATURES	(SPDK_VHOST_DISABLED_FEATURES | \
60 						(1ULL << VIRTIO_SCSI_F_T10_PI ))
61 
62 /* Vhost-user-scsi support protocol features */
63 #define SPDK_VHOST_SCSI_PROTOCOL_FEATURES	(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)
64 
65 #define MGMT_POLL_PERIOD_US (1000 * 5)
66 
67 #define VIRTIO_SCSI_CONTROLQ   0
68 #define VIRTIO_SCSI_EVENTQ   1
69 #define VIRTIO_SCSI_REQUESTQ   2
70 
71 enum spdk_scsi_dev_vhost_status {
72 	/* Target ID is empty. */
73 	VHOST_SCSI_DEV_EMPTY,
74 
75 	/* Target is still being added. */
76 	VHOST_SCSI_DEV_ADDING,
77 
78 	/* Target ID occupied. */
79 	VHOST_SCSI_DEV_PRESENT,
80 
81 	/* Target ID is occupied but removal is in progress. */
82 	VHOST_SCSI_DEV_REMOVING,
83 
84 	/* In session - device (SCSI target) seen but removed. */
85 	VHOST_SCSI_DEV_REMOVED,
86 };
87 
88 /** Context for a SCSI target in a vhost device */
89 struct spdk_scsi_dev_vhost_state {
90 	struct spdk_scsi_dev *dev;
91 	enum spdk_scsi_dev_vhost_status status;
92 	spdk_vhost_event_fn remove_cb;
93 	void *remove_ctx;
94 };
95 
96 struct spdk_vhost_scsi_dev {
97 	int ref;
98 	bool registered;
99 	struct spdk_vhost_dev vdev;
100 	struct spdk_scsi_dev_vhost_state scsi_dev_state[SPDK_VHOST_SCSI_CTRLR_MAX_DEVS];
101 };
102 
103 /** Context for a SCSI target in a vhost session */
104 struct spdk_scsi_dev_session_state {
105 	struct spdk_scsi_dev *dev;
106 	enum spdk_scsi_dev_vhost_status status;
107 };
108 
109 struct spdk_vhost_scsi_session {
110 	struct spdk_vhost_session vsession;
111 
112 	struct spdk_vhost_scsi_dev *svdev;
113 	/** Local copy of the device state */
114 	struct spdk_scsi_dev_session_state scsi_dev_state[SPDK_VHOST_SCSI_CTRLR_MAX_DEVS];
115 	struct spdk_poller *requestq_poller;
116 	struct spdk_poller *mgmt_poller;
117 	struct spdk_poller *stop_poller;
118 };
119 
120 struct spdk_vhost_scsi_task {
121 	struct spdk_scsi_task	scsi;
122 	struct iovec iovs[SPDK_VHOST_IOVS_MAX];
123 
124 	union {
125 		struct virtio_scsi_cmd_resp *resp;
126 		struct virtio_scsi_ctrl_tmf_resp *tmf_resp;
127 	};
128 
129 	struct spdk_vhost_scsi_session *svsession;
130 	struct spdk_scsi_dev *scsi_dev;
131 
132 	/** Number of bytes that were written. */
133 	uint32_t used_len;
134 
135 	int req_idx;
136 
137 	/* If set, the task is currently used for I/O processing. */
138 	bool used;
139 
140 	struct spdk_vhost_virtqueue *vq;
141 };
142 
143 static int vhost_scsi_start(struct spdk_vhost_session *vsession);
144 static int vhost_scsi_stop(struct spdk_vhost_session *vsession);
145 static void vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev,
146 				      struct spdk_json_write_ctx *w);
147 static void vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev,
148 		struct spdk_json_write_ctx *w);
149 static int vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev);
150 static int vhost_scsi_dev_param_changed(struct spdk_vhost_dev *vdev,
151 					unsigned scsi_tgt_num);
152 
153 static const struct spdk_vhost_user_dev_backend spdk_vhost_scsi_user_device_backend = {
154 	.session_ctx_size = sizeof(struct spdk_vhost_scsi_session) - sizeof(struct spdk_vhost_session),
155 	.start_session =  vhost_scsi_start,
156 	.stop_session = vhost_scsi_stop,
157 };
158 
159 static const struct spdk_vhost_dev_backend spdk_vhost_scsi_device_backend = {
160 	.type = VHOST_BACKEND_SCSI,
161 	.dump_info_json = vhost_scsi_dump_info_json,
162 	.write_config_json = vhost_scsi_write_config_json,
163 	.remove_device = vhost_scsi_dev_remove,
164 };
165 
166 static inline void
167 scsi_task_init(struct spdk_vhost_scsi_task *task)
168 {
169 	memset(&task->scsi, 0, sizeof(task->scsi));
170 	/* Tmf_resp pointer and resp pointer are in a union.
171 	 * Here means task->tmf_resp = task->resp = NULL.
172 	 */
173 	task->resp = NULL;
174 	task->used = true;
175 	task->used_len = 0;
176 }
177 
178 static void
179 vhost_scsi_task_put(struct spdk_vhost_scsi_task *task)
180 {
181 	spdk_scsi_task_put(&task->scsi);
182 }
183 
184 static void
185 vhost_scsi_task_free_cb(struct spdk_scsi_task *scsi_task)
186 {
187 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
188 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
189 
190 	assert(vsession->task_cnt > 0);
191 	vsession->task_cnt--;
192 	task->used = false;
193 }
194 
195 static void
196 remove_scsi_tgt(struct spdk_vhost_scsi_dev *svdev,
197 		unsigned scsi_tgt_num)
198 {
199 	struct spdk_scsi_dev_vhost_state *state;
200 	struct spdk_scsi_dev *dev;
201 
202 	state = &svdev->scsi_dev_state[scsi_tgt_num];
203 	dev = state->dev;
204 	state->dev = NULL;
205 	assert(state->status == VHOST_SCSI_DEV_REMOVING);
206 	state->status = VHOST_SCSI_DEV_EMPTY;
207 	spdk_scsi_dev_destruct(dev, NULL, NULL);
208 	if (state->remove_cb) {
209 		state->remove_cb(&svdev->vdev, state->remove_ctx);
210 		state->remove_cb = NULL;
211 	}
212 	SPDK_INFOLOG(vhost, "removed target 'Target %u'\n", scsi_tgt_num);
213 
214 	if (--svdev->ref == 0 && svdev->registered == false) {
215 		free(svdev);
216 	}
217 }
218 
219 static void
220 vhost_scsi_dev_process_removed_cpl_cb(struct spdk_vhost_dev *vdev, void *ctx)
221 {
222 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
223 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
224 					    struct spdk_vhost_scsi_dev, vdev);
225 
226 	/* all sessions have already detached the device */
227 	if (svdev->scsi_dev_state[scsi_tgt_num].status != VHOST_SCSI_DEV_REMOVING) {
228 		/* device was already removed in the meantime */
229 		return;
230 	}
231 
232 	remove_scsi_tgt(svdev, scsi_tgt_num);
233 }
234 
235 static int
236 vhost_scsi_session_process_removed(struct spdk_vhost_dev *vdev,
237 				   struct spdk_vhost_session *vsession, void *ctx)
238 {
239 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
240 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
241 	struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num];
242 
243 	if (state->dev != NULL) {
244 		/* there's still a session that references this device,
245 		 * so abort our foreach chain here. We'll be called
246 		 * again from this session's management poller after it
247 		 * is removed in there
248 		 */
249 		return -1;
250 	}
251 
252 	return 0;
253 }
254 
255 static void
256 process_removed_devs(struct spdk_vhost_scsi_session *svsession)
257 {
258 	struct spdk_scsi_dev *dev;
259 	struct spdk_scsi_dev_session_state *state;
260 	int i;
261 
262 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) {
263 		state = &svsession->scsi_dev_state[i];
264 		dev = state->dev;
265 
266 		if (dev && state->status == VHOST_SCSI_DEV_REMOVING &&
267 		    !spdk_scsi_dev_has_pending_tasks(dev, NULL)) {
268 			/* detach the device from this session */
269 			spdk_scsi_dev_free_io_channels(dev);
270 			state->dev = NULL;
271 			state->status = VHOST_SCSI_DEV_REMOVED;
272 			/* try to detach it globally */
273 			spdk_vhost_lock();
274 			vhost_user_dev_foreach_session(&svsession->svdev->vdev,
275 						       vhost_scsi_session_process_removed,
276 						       vhost_scsi_dev_process_removed_cpl_cb,
277 						       (void *)(uintptr_t)i);
278 			spdk_vhost_unlock();
279 		}
280 	}
281 }
282 
283 static void
284 eventq_enqueue(struct spdk_vhost_scsi_session *svsession, unsigned scsi_dev_num,
285 	       uint32_t event, uint32_t reason)
286 {
287 	struct spdk_vhost_session *vsession = &svsession->vsession;
288 	struct spdk_vhost_virtqueue *vq;
289 	struct vring_desc *desc, *desc_table;
290 	struct virtio_scsi_event *desc_ev;
291 	uint32_t desc_table_size, req_size = 0;
292 	uint16_t req;
293 	int rc;
294 
295 	assert(scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
296 	vq = &vsession->virtqueue[VIRTIO_SCSI_EVENTQ];
297 
298 	if (vq->vring.desc == NULL || vhost_vq_avail_ring_get(vq, &req, 1) != 1) {
299 		SPDK_ERRLOG("%s: failed to send virtio event (no avail ring entries?).\n",
300 			    vsession->name);
301 		return;
302 	}
303 
304 	rc = vhost_vq_get_desc(vsession, vq, req, &desc, &desc_table, &desc_table_size);
305 	if (rc != 0 || desc->len < sizeof(*desc_ev)) {
306 		SPDK_ERRLOG("%s: invalid eventq descriptor at index %"PRIu16".\n",
307 			    vsession->name, req);
308 		goto out;
309 	}
310 
311 	desc_ev = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*desc_ev));
312 	if (desc_ev == NULL) {
313 		SPDK_ERRLOG("%s: eventq descriptor at index %"PRIu16" points "
314 			    "to unmapped guest memory address %p.\n",
315 			    vsession->name, req, (void *)(uintptr_t)desc->addr);
316 		goto out;
317 	}
318 
319 	desc_ev->event = event;
320 	desc_ev->lun[0] = 1;
321 	desc_ev->lun[1] = scsi_dev_num;
322 	/* virtio LUN id 0 can refer either to the entire device
323 	 * or actual LUN 0 (the only supported by vhost for now)
324 	 */
325 	desc_ev->lun[2] = 0 >> 8;
326 	desc_ev->lun[3] = 0 & 0xFF;
327 	/* virtio doesn't specify any strict format for LUN id (bytes 2 and 3)
328 	 * current implementation relies on linux kernel sources
329 	 */
330 	memset(&desc_ev->lun[4], 0, 4);
331 	desc_ev->reason = reason;
332 	req_size = sizeof(*desc_ev);
333 
334 out:
335 	vhost_vq_used_ring_enqueue(vsession, vq, req, req_size);
336 }
337 
338 static void
339 submit_completion(struct spdk_vhost_scsi_task *task)
340 {
341 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
342 
343 	vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
344 				   task->used_len);
345 	SPDK_DEBUGLOG(vhost_scsi, "Finished task (%p) req_idx=%d\n", task, task->req_idx);
346 
347 	vhost_scsi_task_put(task);
348 }
349 
350 static void
351 vhost_scsi_task_mgmt_cpl(struct spdk_scsi_task *scsi_task)
352 {
353 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
354 
355 	submit_completion(task);
356 }
357 
358 static void
359 vhost_scsi_task_cpl(struct spdk_scsi_task *scsi_task)
360 {
361 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
362 
363 	/* The SCSI task has completed.  Do final processing and then post
364 	   notification to the virtqueue's "used" ring.
365 	 */
366 	task->resp->status = task->scsi.status;
367 
368 	if (task->scsi.status != SPDK_SCSI_STATUS_GOOD) {
369 		memcpy(task->resp->sense, task->scsi.sense_data, task->scsi.sense_data_len);
370 		task->resp->sense_len = task->scsi.sense_data_len;
371 		SPDK_DEBUGLOG(vhost_scsi, "Task (%p) req_idx=%d failed - status=%u\n", task, task->req_idx,
372 			      task->scsi.status);
373 	}
374 	assert(task->scsi.transfer_len == task->scsi.length);
375 	task->resp->resid = task->scsi.length - task->scsi.data_transferred;
376 
377 	submit_completion(task);
378 }
379 
380 static void
381 task_submit(struct spdk_vhost_scsi_task *task)
382 {
383 	task->resp->response = VIRTIO_SCSI_S_OK;
384 	spdk_scsi_dev_queue_task(task->scsi_dev, &task->scsi);
385 }
386 
387 static void
388 mgmt_task_submit(struct spdk_vhost_scsi_task *task, enum spdk_scsi_task_func func)
389 {
390 	task->tmf_resp->response = VIRTIO_SCSI_S_OK;
391 	task->scsi.function = func;
392 	spdk_scsi_dev_queue_mgmt_task(task->scsi_dev, &task->scsi);
393 }
394 
395 static void
396 invalid_request(struct spdk_vhost_scsi_task *task)
397 {
398 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
399 
400 	vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
401 				   task->used_len);
402 	vhost_scsi_task_put(task);
403 
404 	SPDK_DEBUGLOG(vhost_scsi, "Invalid request (status=%" PRIu8")\n",
405 		      task->resp ? task->resp->response : -1);
406 }
407 
408 static int
409 vhost_scsi_task_init_target(struct spdk_vhost_scsi_task *task, const __u8 *lun)
410 {
411 	struct spdk_vhost_scsi_session *svsession = task->svsession;
412 	struct spdk_scsi_dev_session_state *state;
413 	uint16_t lun_id = (((uint16_t)lun[2] << 8) | lun[3]) & 0x3FFF;
414 
415 	SPDK_LOGDUMP(vhost_scsi_queue, "LUN", lun, 8);
416 
417 	/* First byte must be 1 and second is target */
418 	if (lun[0] != 1 || lun[1] >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
419 		return -1;
420 	}
421 
422 	state = &svsession->scsi_dev_state[lun[1]];
423 	task->scsi_dev = state->dev;
424 	if (state->dev == NULL || state->status != VHOST_SCSI_DEV_PRESENT) {
425 		/* If dev has been hotdetached, return 0 to allow sending
426 		 * additional hotremove event via sense codes.
427 		 */
428 		return state->status != VHOST_SCSI_DEV_EMPTY ? 0 : -1;
429 	}
430 
431 	task->scsi.target_port = spdk_scsi_dev_find_port_by_id(task->scsi_dev, 0);
432 	task->scsi.lun = spdk_scsi_dev_get_lun(state->dev, lun_id);
433 	return 0;
434 }
435 
436 static void
437 process_ctrl_request(struct spdk_vhost_scsi_task *task)
438 {
439 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
440 	struct vring_desc *desc, *desc_table;
441 	struct virtio_scsi_ctrl_tmf_req *ctrl_req;
442 	struct virtio_scsi_ctrl_an_resp *an_resp;
443 	uint32_t desc_table_size, used_len = 0;
444 	int rc;
445 
446 	spdk_scsi_task_construct(&task->scsi, vhost_scsi_task_mgmt_cpl, vhost_scsi_task_free_cb);
447 	rc = vhost_vq_get_desc(vsession, task->vq, task->req_idx, &desc, &desc_table,
448 			       &desc_table_size);
449 	if (spdk_unlikely(rc != 0)) {
450 		SPDK_ERRLOG("%s: invalid controlq descriptor at index %d.\n",
451 			    vsession->name, task->req_idx);
452 		goto out;
453 	}
454 
455 	ctrl_req = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*ctrl_req));
456 	if (ctrl_req == NULL) {
457 		SPDK_ERRLOG("%s: invalid task management request at index %d.\n",
458 			    vsession->name, task->req_idx);
459 		goto out;
460 	}
461 
462 	SPDK_DEBUGLOG(vhost_scsi_queue,
463 		      "Processing controlq descriptor: desc %d/%p, desc_addr %p, len %d, flags %d, last_used_idx %d; kickfd %d; size %d\n",
464 		      task->req_idx, desc, (void *)desc->addr, desc->len, desc->flags, task->vq->last_used_idx,
465 		      task->vq->vring.kickfd, task->vq->vring.size);
466 	SPDK_LOGDUMP(vhost_scsi_queue, "Request descriptor", (uint8_t *)ctrl_req, desc->len);
467 
468 	vhost_scsi_task_init_target(task, ctrl_req->lun);
469 
470 	vhost_vring_desc_get_next(&desc, desc_table, desc_table_size);
471 	if (spdk_unlikely(desc == NULL)) {
472 		SPDK_ERRLOG("%s: no response descriptor for controlq request %d.\n",
473 			    vsession->name, task->req_idx);
474 		goto out;
475 	}
476 
477 	/* Process the TMF request */
478 	switch (ctrl_req->type) {
479 	case VIRTIO_SCSI_T_TMF:
480 		task->tmf_resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->tmf_resp));
481 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_tmf_resp) || task->tmf_resp == NULL)) {
482 			SPDK_ERRLOG("%s: TMF response descriptor at index %d points to invalid guest memory region\n",
483 				    vsession->name, task->req_idx);
484 			goto out;
485 		}
486 
487 		/* Check if we are processing a valid request */
488 		if (task->scsi_dev == NULL) {
489 			task->tmf_resp->response = VIRTIO_SCSI_S_BAD_TARGET;
490 			break;
491 		}
492 
493 		switch (ctrl_req->subtype) {
494 		case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
495 			/* Handle LUN reset */
496 			SPDK_DEBUGLOG(vhost_scsi_queue, "%s: LUN reset\n", vsession->name);
497 
498 			mgmt_task_submit(task, SPDK_SCSI_TASK_FUNC_LUN_RESET);
499 			return;
500 		default:
501 			task->tmf_resp->response = VIRTIO_SCSI_S_ABORTED;
502 			/* Unsupported command */
503 			SPDK_DEBUGLOG(vhost_scsi_queue, "%s: unsupported TMF command %x\n",
504 				      vsession->name, ctrl_req->subtype);
505 			break;
506 		}
507 		break;
508 	case VIRTIO_SCSI_T_AN_QUERY:
509 	case VIRTIO_SCSI_T_AN_SUBSCRIBE: {
510 		an_resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*an_resp));
511 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_an_resp) || an_resp == NULL)) {
512 			SPDK_WARNLOG("%s: asynchronous response descriptor points to invalid guest memory region\n",
513 				     vsession->name);
514 			goto out;
515 		}
516 
517 		an_resp->response = VIRTIO_SCSI_S_ABORTED;
518 		break;
519 	}
520 	default:
521 		SPDK_DEBUGLOG(vhost_scsi_queue, "%s: Unsupported control command %x\n",
522 			      vsession->name, ctrl_req->type);
523 		break;
524 	}
525 
526 	used_len = sizeof(struct virtio_scsi_ctrl_tmf_resp);
527 out:
528 	vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx, used_len);
529 	vhost_scsi_task_put(task);
530 }
531 
532 /*
533  * Process task's descriptor chain and setup data related fields.
534  * Return
535  *   -1 if request is invalid and must be aborted,
536  *    0 if all data are set.
537  */
538 static int
539 task_data_setup(struct spdk_vhost_scsi_task *task,
540 		struct virtio_scsi_cmd_req **req)
541 {
542 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
543 	struct vring_desc *desc, *desc_table;
544 	struct iovec *iovs = task->iovs;
545 	uint16_t iovcnt = 0;
546 	uint32_t desc_table_len, len = 0;
547 	int rc;
548 
549 	spdk_scsi_task_construct(&task->scsi, vhost_scsi_task_cpl, vhost_scsi_task_free_cb);
550 
551 	rc = vhost_vq_get_desc(vsession, task->vq, task->req_idx, &desc, &desc_table, &desc_table_len);
552 	/* First descriptor must be readable */
553 	if (spdk_unlikely(rc != 0  || vhost_vring_desc_is_wr(desc) ||
554 			  desc->len < sizeof(struct virtio_scsi_cmd_req))) {
555 		SPDK_WARNLOG("%s: invalid first request descriptor at index %"PRIu16".\n",
556 			     vsession->name, task->req_idx);
557 		goto invalid_task;
558 	}
559 
560 	*req = vhost_gpa_to_vva(vsession, desc->addr, sizeof(**req));
561 	if (spdk_unlikely(*req == NULL)) {
562 		SPDK_WARNLOG("%s: request descriptor at index %d points to invalid guest memory region\n",
563 			     vsession->name, task->req_idx);
564 		goto invalid_task;
565 	}
566 
567 	/* Each request must have at least 2 descriptors (e.g. request and response) */
568 	vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
569 	if (desc == NULL) {
570 		SPDK_WARNLOG("%s: descriptor chain at index %d contains neither payload nor response buffer.\n",
571 			     vsession->name, task->req_idx);
572 		goto invalid_task;
573 	}
574 	task->scsi.dxfer_dir = vhost_vring_desc_is_wr(desc) ? SPDK_SCSI_DIR_FROM_DEV :
575 			       SPDK_SCSI_DIR_TO_DEV;
576 	task->scsi.iovs = iovs;
577 
578 	if (task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV) {
579 		/*
580 		 * FROM_DEV (READ): [RD_req][WR_resp][WR_buf0]...[WR_bufN]
581 		 */
582 		task->resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->resp));
583 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) {
584 			SPDK_WARNLOG("%s: response descriptor at index %d points to invalid guest memory region\n",
585 				     vsession->name, task->req_idx);
586 			goto invalid_task;
587 		}
588 		rc = vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
589 		if (spdk_unlikely(rc != 0)) {
590 			SPDK_WARNLOG("%s: invalid descriptor chain at request index %d (descriptor id overflow?).\n",
591 				     vsession->name, task->req_idx);
592 			goto invalid_task;
593 		}
594 
595 		if (desc == NULL) {
596 			/*
597 			 * TEST UNIT READY command and some others might not contain any payload and this is not an error.
598 			 */
599 			SPDK_DEBUGLOG(vhost_scsi_data,
600 				      "No payload descriptors for FROM DEV command req_idx=%"PRIu16".\n", task->req_idx);
601 			SPDK_LOGDUMP(vhost_scsi_data, "CDB=", (*req)->cdb, VIRTIO_SCSI_CDB_SIZE);
602 			task->used_len = sizeof(struct virtio_scsi_cmd_resp);
603 			task->scsi.iovcnt = 1;
604 			task->scsi.iovs[0].iov_len = 0;
605 			task->scsi.length = 0;
606 			task->scsi.transfer_len = 0;
607 			return 0;
608 		}
609 
610 		/* All remaining descriptors are data. */
611 		while (desc) {
612 			if (spdk_unlikely(!vhost_vring_desc_is_wr(desc))) {
613 				SPDK_WARNLOG("%s: FROM DEV cmd: descriptor nr %" PRIu16" in payload chain is read only.\n",
614 					     vsession->name, iovcnt);
615 				goto invalid_task;
616 			}
617 
618 			if (spdk_unlikely(vhost_vring_desc_to_iov(vsession, iovs, &iovcnt, desc))) {
619 				goto invalid_task;
620 			}
621 			len += desc->len;
622 
623 			rc = vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
624 			if (spdk_unlikely(rc != 0)) {
625 				SPDK_WARNLOG("%s: invalid payload in descriptor chain starting at index %d.\n",
626 					     vsession->name, task->req_idx);
627 				goto invalid_task;
628 			}
629 		}
630 
631 		task->used_len = sizeof(struct virtio_scsi_cmd_resp) + len;
632 	} else {
633 		SPDK_DEBUGLOG(vhost_scsi_data, "TO DEV");
634 		/*
635 		 * TO_DEV (WRITE):[RD_req][RD_buf0]...[RD_bufN][WR_resp]
636 		 * No need to check descriptor WR flag as this is done while setting scsi.dxfer_dir.
637 		 */
638 
639 		/* Process descriptors up to response. */
640 		while (!vhost_vring_desc_is_wr(desc)) {
641 			if (spdk_unlikely(vhost_vring_desc_to_iov(vsession, iovs, &iovcnt, desc))) {
642 				goto invalid_task;
643 			}
644 			len += desc->len;
645 
646 			vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
647 			if (spdk_unlikely(desc == NULL)) {
648 				SPDK_WARNLOG("%s: TO_DEV cmd: no response descriptor.\n", vsession->name);
649 				goto invalid_task;
650 			}
651 		}
652 
653 		task->resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->resp));
654 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) {
655 			SPDK_WARNLOG("%s: response descriptor at index %d points to invalid guest memory region\n",
656 				     vsession->name, task->req_idx);
657 			goto invalid_task;
658 		}
659 
660 		task->used_len = sizeof(struct virtio_scsi_cmd_resp);
661 	}
662 
663 	task->scsi.iovcnt = iovcnt;
664 	task->scsi.length = len;
665 	task->scsi.transfer_len = len;
666 	return 0;
667 
668 invalid_task:
669 	SPDK_DEBUGLOG(vhost_scsi_data, "%s: Invalid task at index %"PRIu16".\n",
670 		      vsession->name, task->req_idx);
671 	return -1;
672 }
673 
674 static int
675 process_request(struct spdk_vhost_scsi_task *task)
676 {
677 	struct virtio_scsi_cmd_req *req;
678 	int result;
679 
680 	result = task_data_setup(task, &req);
681 	if (result) {
682 		return result;
683 	}
684 
685 	result = vhost_scsi_task_init_target(task, req->lun);
686 	if (spdk_unlikely(result != 0)) {
687 		task->resp->response = VIRTIO_SCSI_S_BAD_TARGET;
688 		return -1;
689 	}
690 
691 	task->scsi.cdb = req->cdb;
692 	SPDK_LOGDUMP(vhost_scsi_data, "request CDB", req->cdb, VIRTIO_SCSI_CDB_SIZE);
693 
694 	if (spdk_unlikely(task->scsi.lun == NULL)) {
695 		spdk_scsi_task_process_null_lun(&task->scsi);
696 		task->resp->response = VIRTIO_SCSI_S_OK;
697 		return 1;
698 	}
699 
700 	return 0;
701 }
702 
703 static void
704 process_scsi_task(struct spdk_vhost_session *vsession,
705 		  struct spdk_vhost_virtqueue *vq,
706 		  uint16_t req_idx)
707 {
708 	struct spdk_vhost_scsi_task *task;
709 	int result;
710 
711 	task = &((struct spdk_vhost_scsi_task *)vq->tasks)[req_idx];
712 	if (spdk_unlikely(task->used)) {
713 		SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
714 			    vsession->name, req_idx);
715 		vhost_vq_used_ring_enqueue(vsession, vq, req_idx, 0);
716 		return;
717 	}
718 
719 	vsession->task_cnt++;
720 	scsi_task_init(task);
721 
722 	if (spdk_unlikely(vq->vring_idx == VIRTIO_SCSI_CONTROLQ)) {
723 		process_ctrl_request(task);
724 	} else {
725 		result = process_request(task);
726 		if (likely(result == 0)) {
727 			task_submit(task);
728 			SPDK_DEBUGLOG(vhost_scsi, "====== Task %p req_idx %d submitted ======\n", task,
729 				      task->req_idx);
730 		} else if (result > 0) {
731 			vhost_scsi_task_cpl(&task->scsi);
732 			SPDK_DEBUGLOG(vhost_scsi, "====== Task %p req_idx %d finished early ======\n", task,
733 				      task->req_idx);
734 		} else {
735 			invalid_request(task);
736 			SPDK_DEBUGLOG(vhost_scsi, "====== Task %p req_idx %d failed ======\n", task,
737 				      task->req_idx);
738 		}
739 	}
740 }
741 
742 static void
743 submit_inflight_desc(struct spdk_vhost_scsi_session *svsession,
744 		     struct spdk_vhost_virtqueue *vq)
745 {
746 	struct spdk_vhost_session *vsession;
747 	spdk_vhost_resubmit_info *resubmit;
748 	spdk_vhost_resubmit_desc *resubmit_list;
749 	uint16_t req_idx;
750 	int i;
751 
752 	resubmit = vq->vring_inflight.resubmit_inflight;
753 	if (spdk_likely(resubmit == NULL || resubmit->resubmit_list == NULL ||
754 			resubmit->resubmit_num == 0)) {
755 		return;
756 	}
757 
758 	resubmit_list = resubmit->resubmit_list;
759 	vsession = &svsession->vsession;
760 
761 	for (i = resubmit->resubmit_num - 1; i >= 0; --i) {
762 		req_idx = resubmit_list[resubmit->resubmit_num].index;
763 		SPDK_DEBUGLOG(vhost_scsi, "====== Start processing resubmit request idx %"PRIu16"======\n",
764 			      req_idx);
765 
766 		if (spdk_unlikely(req_idx >= vq->vring.size)) {
767 			SPDK_ERRLOG("%s: request idx '%"PRIu16"' exceeds virtqueue size (%"PRIu16").\n",
768 				    vsession->name, req_idx, vq->vring.size);
769 			vhost_vq_used_ring_enqueue(vsession, vq, req_idx, 0);
770 			continue;
771 		}
772 
773 		process_scsi_task(vsession, vq, req_idx);
774 	}
775 
776 	resubmit->resubmit_num = 0;
777 }
778 
779 static int
780 process_vq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_virtqueue *vq)
781 {
782 	struct spdk_vhost_session *vsession = &svsession->vsession;
783 	uint16_t reqs[32];
784 	uint16_t reqs_cnt, i;
785 
786 	submit_inflight_desc(svsession, vq);
787 
788 	reqs_cnt = vhost_vq_avail_ring_get(vq, reqs, SPDK_COUNTOF(reqs));
789 	assert(reqs_cnt <= 32);
790 
791 	for (i = 0; i < reqs_cnt; i++) {
792 		SPDK_DEBUGLOG(vhost_scsi, "====== Starting processing request idx %"PRIu16"======\n",
793 			      reqs[i]);
794 
795 		if (spdk_unlikely(reqs[i] >= vq->vring.size)) {
796 			SPDK_ERRLOG("%s: request idx '%"PRIu16"' exceeds virtqueue size (%"PRIu16").\n",
797 				    vsession->name, reqs[i], vq->vring.size);
798 			vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
799 			continue;
800 		}
801 
802 		rte_vhost_set_inflight_desc_split(vsession->vid, vq->vring_idx, reqs[i]);
803 
804 		process_scsi_task(vsession, vq, reqs[i]);
805 	}
806 
807 	return reqs_cnt;
808 }
809 
810 static int
811 vdev_mgmt_worker(void *arg)
812 {
813 	struct spdk_vhost_scsi_session *svsession = arg;
814 	struct spdk_vhost_session *vsession = &svsession->vsession;
815 	int rc = 0;
816 
817 	process_removed_devs(svsession);
818 
819 	if (vsession->virtqueue[VIRTIO_SCSI_EVENTQ].vring.desc) {
820 		vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]);
821 	}
822 
823 	if (vsession->virtqueue[VIRTIO_SCSI_CONTROLQ].vring.desc) {
824 		rc = process_vq(svsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);
825 		vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);
826 	}
827 
828 	return rc > 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
829 }
830 
831 static int
832 vdev_worker(void *arg)
833 {
834 	struct spdk_vhost_scsi_session *svsession = arg;
835 	struct spdk_vhost_session *vsession = &svsession->vsession;
836 	uint32_t q_idx;
837 	int rc = 0;
838 
839 	for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vsession->max_queues; q_idx++) {
840 		rc = process_vq(svsession, &vsession->virtqueue[q_idx]);
841 	}
842 
843 	vhost_session_used_signal(vsession);
844 
845 	return rc > 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
846 }
847 
848 static struct spdk_vhost_scsi_dev *
849 to_scsi_dev(struct spdk_vhost_dev *ctrlr)
850 {
851 	if (ctrlr == NULL) {
852 		return NULL;
853 	}
854 
855 	if (ctrlr->backend->type != VHOST_BACKEND_SCSI) {
856 		SPDK_ERRLOG("%s: not a vhost-scsi device.\n", ctrlr->name);
857 		return NULL;
858 	}
859 
860 	return SPDK_CONTAINEROF(ctrlr, struct spdk_vhost_scsi_dev, vdev);
861 }
862 
863 static struct spdk_vhost_scsi_session *
864 to_scsi_session(struct spdk_vhost_session *vsession)
865 {
866 	assert(vsession->vdev->backend->type == VHOST_BACKEND_SCSI);
867 	return (struct spdk_vhost_scsi_session *)vsession;
868 }
869 
870 int
871 spdk_vhost_scsi_dev_construct(const char *name, const char *cpumask)
872 {
873 	struct spdk_vhost_scsi_dev *svdev = calloc(1, sizeof(*svdev));
874 	int rc;
875 
876 	if (svdev == NULL) {
877 		return -ENOMEM;
878 	}
879 
880 	svdev->vdev.virtio_features = SPDK_VHOST_SCSI_FEATURES;
881 	svdev->vdev.disabled_features = SPDK_VHOST_SCSI_DISABLED_FEATURES;
882 	svdev->vdev.protocol_features = SPDK_VHOST_SCSI_PROTOCOL_FEATURES;
883 
884 	spdk_vhost_lock();
885 	rc = vhost_dev_register(&svdev->vdev, name, cpumask,
886 				&spdk_vhost_scsi_device_backend,
887 				&spdk_vhost_scsi_user_device_backend);
888 	if (rc) {
889 		free(svdev);
890 		spdk_vhost_unlock();
891 		return rc;
892 	}
893 
894 	svdev->registered = true;
895 
896 	spdk_vhost_unlock();
897 	return rc;
898 }
899 
900 static int
901 vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev)
902 {
903 	struct spdk_vhost_scsi_dev *svdev = to_scsi_dev(vdev);
904 	struct spdk_vhost_user_dev *user_dev = vdev->ctxt;
905 	int rc, i;
906 
907 	if (user_dev->pending_async_op_num) {
908 		return -EBUSY;
909 	}
910 
911 	assert(svdev != NULL);
912 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) {
913 		if (svdev->scsi_dev_state[i].dev) {
914 			if (vdev->registered) {
915 				SPDK_ERRLOG("%s: SCSI target %d is still present.\n", vdev->name, i);
916 				return -EBUSY;
917 			}
918 
919 			rc = spdk_vhost_scsi_dev_remove_tgt(vdev, i, NULL, NULL);
920 			if (rc != 0) {
921 				SPDK_ERRLOG("%s: failed to force-remove target %d\n", vdev->name, i);
922 				return rc;
923 			}
924 		}
925 	}
926 
927 	rc = vhost_dev_unregister(vdev);
928 	if (rc != 0) {
929 		return rc;
930 	}
931 	svdev->registered = false;
932 
933 	if (svdev->ref == 0) {
934 		free(svdev);
935 	}
936 
937 	return 0;
938 }
939 
940 struct spdk_scsi_dev *
941 spdk_vhost_scsi_dev_get_tgt(struct spdk_vhost_dev *vdev, uint8_t num)
942 {
943 	struct spdk_vhost_scsi_dev *svdev;
944 
945 	assert(num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
946 	svdev = to_scsi_dev(vdev);
947 	assert(svdev != NULL);
948 	if (svdev->scsi_dev_state[num].status != VHOST_SCSI_DEV_PRESENT) {
949 		return NULL;
950 	}
951 
952 	assert(svdev->scsi_dev_state[num].dev != NULL);
953 	return svdev->scsi_dev_state[num].dev;
954 }
955 
956 static unsigned
957 get_scsi_dev_num(const struct spdk_vhost_scsi_dev *svdev,
958 		 const struct spdk_scsi_lun *lun)
959 {
960 	const struct spdk_scsi_dev *scsi_dev;
961 	unsigned scsi_dev_num;
962 
963 	assert(lun != NULL);
964 	assert(svdev != NULL);
965 	scsi_dev = spdk_scsi_lun_get_dev(lun);
966 	for (scsi_dev_num = 0; scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_dev_num++) {
967 		if (svdev->scsi_dev_state[scsi_dev_num].dev == scsi_dev) {
968 			break;
969 		}
970 	}
971 
972 	return scsi_dev_num;
973 }
974 
975 static void
976 vhost_scsi_lun_resize(const struct spdk_scsi_lun *lun, void *arg)
977 {
978 	struct spdk_vhost_scsi_dev *svdev = arg;
979 	unsigned scsi_dev_num;
980 
981 	scsi_dev_num = get_scsi_dev_num(svdev, lun);
982 	if (scsi_dev_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
983 		/* The entire device has been already removed. */
984 		return;
985 	}
986 
987 	vhost_scsi_dev_param_changed(&svdev->vdev, scsi_dev_num);
988 }
989 
990 static void
991 vhost_scsi_lun_hotremove(const struct spdk_scsi_lun *lun, void *arg)
992 {
993 	struct spdk_vhost_scsi_dev *svdev = arg;
994 	unsigned scsi_dev_num;
995 
996 	scsi_dev_num = get_scsi_dev_num(svdev, lun);
997 	if (scsi_dev_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
998 		/* The entire device has been already removed. */
999 		return;
1000 	}
1001 
1002 	/* remove entire device */
1003 	spdk_vhost_scsi_dev_remove_tgt(&svdev->vdev, scsi_dev_num, NULL, NULL);
1004 }
1005 
1006 static void
1007 vhost_scsi_dev_add_tgt_cpl_cb(struct spdk_vhost_dev *vdev, void *ctx)
1008 {
1009 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
1010 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
1011 					    struct spdk_vhost_scsi_dev, vdev);
1012 	struct spdk_scsi_dev_vhost_state *vhost_sdev;
1013 
1014 	vhost_sdev = &svdev->scsi_dev_state[scsi_tgt_num];
1015 
1016 	/* All sessions have added the target */
1017 	assert(vhost_sdev->status == VHOST_SCSI_DEV_ADDING);
1018 	vhost_sdev->status = VHOST_SCSI_DEV_PRESENT;
1019 	svdev->ref++;
1020 }
1021 
1022 static int
1023 vhost_scsi_session_add_tgt(struct spdk_vhost_dev *vdev,
1024 			   struct spdk_vhost_session *vsession, void *ctx)
1025 {
1026 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
1027 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
1028 	struct spdk_scsi_dev_session_state *session_sdev = &svsession->scsi_dev_state[scsi_tgt_num];
1029 	struct spdk_scsi_dev_vhost_state *vhost_sdev;
1030 	int rc;
1031 
1032 	if (!vsession->started || session_sdev->dev != NULL) {
1033 		/* Nothing to do. */
1034 		return 0;
1035 	}
1036 
1037 	vhost_sdev = &svsession->svdev->scsi_dev_state[scsi_tgt_num];
1038 	session_sdev->dev = vhost_sdev->dev;
1039 	session_sdev->status = VHOST_SCSI_DEV_PRESENT;
1040 
1041 	rc = spdk_scsi_dev_allocate_io_channels(svsession->scsi_dev_state[scsi_tgt_num].dev);
1042 	if (rc != 0) {
1043 		SPDK_ERRLOG("%s: Couldn't allocate io channel for SCSI target %u.\n",
1044 			    vsession->name, scsi_tgt_num);
1045 
1046 		/* unset the SCSI target so that all I/O to it will be rejected */
1047 		session_sdev->dev = NULL;
1048 		/* Set status to EMPTY so that we won't reply with SCSI hotremove
1049 		 * sense codes - the device hasn't ever been added.
1050 		 */
1051 		session_sdev->status = VHOST_SCSI_DEV_EMPTY;
1052 
1053 		/* Return with no error. We'll continue allocating io_channels for
1054 		 * other sessions on this device in hopes they succeed. The sessions
1055 		 * that failed to allocate io_channels simply won't be able to
1056 		 * detect the SCSI target, nor do any I/O to it.
1057 		 */
1058 		return 0;
1059 	}
1060 
1061 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) {
1062 		eventq_enqueue(svsession, scsi_tgt_num,
1063 			       VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_RESCAN);
1064 	} else {
1065 		SPDK_NOTICELOG("%s: driver does not support hotplug. "
1066 			       "Please restart it or perform a rescan.\n",
1067 			       vsession->name);
1068 	}
1069 
1070 	return 0;
1071 }
1072 
1073 int
1074 spdk_vhost_scsi_dev_add_tgt(struct spdk_vhost_dev *vdev, int scsi_tgt_num,
1075 			    const char *bdev_name)
1076 {
1077 	struct spdk_vhost_scsi_dev *svdev;
1078 	struct spdk_scsi_dev_vhost_state *state;
1079 	char target_name[SPDK_SCSI_DEV_MAX_NAME];
1080 	int lun_id_list[1];
1081 	const char *bdev_names_list[1];
1082 
1083 	svdev = to_scsi_dev(vdev);
1084 	if (!svdev) {
1085 		SPDK_ERRLOG("Before adding a SCSI target, there should be a SCSI device.");
1086 		return -EINVAL;
1087 	}
1088 
1089 	if (scsi_tgt_num < 0) {
1090 		for (scsi_tgt_num = 0; scsi_tgt_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_tgt_num++) {
1091 			if (svdev->scsi_dev_state[scsi_tgt_num].dev == NULL) {
1092 				break;
1093 			}
1094 		}
1095 
1096 		if (scsi_tgt_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1097 			SPDK_ERRLOG("%s: all SCSI target slots are already in use.\n", vdev->name);
1098 			return -ENOSPC;
1099 		}
1100 	} else {
1101 		if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1102 			SPDK_ERRLOG("%s: SCSI target number is too big (got %d, max %d), started from 0.\n",
1103 				    vdev->name, scsi_tgt_num, SPDK_VHOST_SCSI_CTRLR_MAX_DEVS - 1);
1104 			return -EINVAL;
1105 		}
1106 	}
1107 
1108 	if (bdev_name == NULL) {
1109 		SPDK_ERRLOG("No lun name specified\n");
1110 		return -EINVAL;
1111 	}
1112 
1113 	state = &svdev->scsi_dev_state[scsi_tgt_num];
1114 	if (state->dev != NULL) {
1115 		SPDK_ERRLOG("%s: SCSI target %u already occupied\n", vdev->name, scsi_tgt_num);
1116 		return -EEXIST;
1117 	}
1118 
1119 	/*
1120 	 * At this stage only one LUN per target
1121 	 */
1122 	snprintf(target_name, sizeof(target_name), "Target %u", scsi_tgt_num);
1123 	lun_id_list[0] = 0;
1124 	bdev_names_list[0] = (char *)bdev_name;
1125 
1126 	state->status = VHOST_SCSI_DEV_ADDING;
1127 	state->dev = spdk_scsi_dev_construct_ext(target_name, bdev_names_list, lun_id_list, 1,
1128 			SPDK_SPC_PROTOCOL_IDENTIFIER_SAS,
1129 			vhost_scsi_lun_resize, svdev,
1130 			vhost_scsi_lun_hotremove, svdev);
1131 
1132 	if (state->dev == NULL) {
1133 		state->status = VHOST_SCSI_DEV_EMPTY;
1134 		SPDK_ERRLOG("%s: couldn't create SCSI target %u using bdev '%s'\n",
1135 			    vdev->name, scsi_tgt_num, bdev_name);
1136 		return -EINVAL;
1137 	}
1138 	spdk_scsi_dev_add_port(state->dev, 0, "vhost");
1139 
1140 	SPDK_INFOLOG(vhost, "%s: added SCSI target %u using bdev '%s'\n",
1141 		     vdev->name, scsi_tgt_num, bdev_name);
1142 
1143 	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_add_tgt,
1144 				       vhost_scsi_dev_add_tgt_cpl_cb,
1145 				       (void *)(uintptr_t)scsi_tgt_num);
1146 	return scsi_tgt_num;
1147 }
1148 
1149 struct scsi_tgt_hotplug_ctx {
1150 	unsigned scsi_tgt_num;
1151 	bool async_fini;
1152 };
1153 
1154 static void
1155 vhost_scsi_dev_remove_tgt_cpl_cb(struct spdk_vhost_dev *vdev, void *_ctx)
1156 {
1157 	struct scsi_tgt_hotplug_ctx *ctx = _ctx;
1158 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
1159 					    struct spdk_vhost_scsi_dev, vdev);
1160 
1161 	if (!ctx->async_fini) {
1162 		/* there aren't any active sessions, so remove the dev and exit */
1163 		remove_scsi_tgt(svdev, ctx->scsi_tgt_num);
1164 	}
1165 
1166 	free(ctx);
1167 }
1168 
1169 static int
1170 vhost_scsi_session_remove_tgt(struct spdk_vhost_dev *vdev,
1171 			      struct spdk_vhost_session *vsession, void *_ctx)
1172 {
1173 	struct scsi_tgt_hotplug_ctx *ctx = _ctx;
1174 	unsigned scsi_tgt_num = ctx->scsi_tgt_num;
1175 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
1176 	struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num];
1177 
1178 	if (!vsession->started || state->dev == NULL) {
1179 		/* Nothing to do */
1180 		return 0;
1181 	}
1182 
1183 	/* Mark the target for removal */
1184 	assert(state->status == VHOST_SCSI_DEV_PRESENT);
1185 	state->status = VHOST_SCSI_DEV_REMOVING;
1186 
1187 	/* Send a hotremove virtio event */
1188 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) {
1189 		eventq_enqueue(svsession, scsi_tgt_num,
1190 			       VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_REMOVED);
1191 	}
1192 
1193 	/* Wait for the session's management poller to remove the target after
1194 	 * all its pending I/O has finished.
1195 	 */
1196 	ctx->async_fini = true;
1197 	return 0;
1198 }
1199 
1200 int
1201 spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num,
1202 			       spdk_vhost_event_fn cb_fn, void *cb_arg)
1203 {
1204 	struct spdk_vhost_scsi_dev *svdev;
1205 	struct spdk_scsi_dev_vhost_state *scsi_dev_state;
1206 	struct scsi_tgt_hotplug_ctx *ctx;
1207 
1208 	if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1209 		SPDK_ERRLOG("%s: invalid SCSI target number %d\n", vdev->name, scsi_tgt_num);
1210 		return -EINVAL;
1211 	}
1212 
1213 	svdev = to_scsi_dev(vdev);
1214 	if (!svdev) {
1215 		SPDK_ERRLOG("An invalid SCSI device that removing from a SCSI target.");
1216 		return -EINVAL;
1217 	}
1218 
1219 	scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num];
1220 
1221 	if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) {
1222 		return -EBUSY;
1223 	}
1224 
1225 	if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) {
1226 		SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num);
1227 		return -ENODEV;
1228 	}
1229 
1230 	assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY);
1231 	ctx = calloc(1, sizeof(*ctx));
1232 	if (ctx == NULL) {
1233 		SPDK_ERRLOG("calloc failed\n");
1234 		return -ENOMEM;
1235 	}
1236 
1237 	ctx->scsi_tgt_num = scsi_tgt_num;
1238 	ctx->async_fini = false;
1239 
1240 	scsi_dev_state->remove_cb = cb_fn;
1241 	scsi_dev_state->remove_ctx = cb_arg;
1242 	scsi_dev_state->status = VHOST_SCSI_DEV_REMOVING;
1243 
1244 	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_remove_tgt,
1245 				       vhost_scsi_dev_remove_tgt_cpl_cb, ctx);
1246 	return 0;
1247 }
1248 
1249 static int
1250 vhost_scsi_session_param_changed(struct spdk_vhost_dev *vdev,
1251 				 struct spdk_vhost_session *vsession, void *ctx)
1252 {
1253 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
1254 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
1255 	struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num];
1256 
1257 	if (!vsession->started || state->dev == NULL) {
1258 		/* Nothing to do */
1259 		return 0;
1260 	}
1261 
1262 	/* Send a parameter change virtio event */
1263 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_CHANGE)) {
1264 		/*
1265 		 * virtio 1.0 spec says:
1266 		 * By sending this event, the device signals a change in the configuration
1267 		 * parameters of a logical unit, for example the capacity or cache mode.
1268 		 * event is set to VIRTIO_SCSI_T_PARAM_CHANGE. lun addresses a logical unit
1269 		 * in the SCSI host. The same event SHOULD also be reported as a unit
1270 		 * attention condition. reason contains the additional sense code and
1271 		 * additional sense code qualifier, respectively in bits 0…7 and 8…15.
1272 		 * Note: For example, a change in * capacity will be reported as asc
1273 		 * 0x2a, ascq 0x09 (CAPACITY DATA HAS CHANGED).
1274 		 */
1275 		eventq_enqueue(svsession, scsi_tgt_num, VIRTIO_SCSI_T_PARAM_CHANGE, 0x2a | (0x09 << 8));
1276 	}
1277 
1278 	return 0;
1279 }
1280 
1281 static int
1282 vhost_scsi_dev_param_changed(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num)
1283 {
1284 	struct spdk_vhost_scsi_dev *svdev;
1285 	struct spdk_scsi_dev_vhost_state *scsi_dev_state;
1286 
1287 	if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1288 		SPDK_ERRLOG("%s: invalid SCSI target number %d\n", vdev->name, scsi_tgt_num);
1289 		return -EINVAL;
1290 	}
1291 
1292 	svdev = to_scsi_dev(vdev);
1293 	if (!svdev) {
1294 		SPDK_ERRLOG("An invalid SCSI device that removing from a SCSI target.");
1295 		return -EINVAL;
1296 	}
1297 
1298 	scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num];
1299 
1300 	if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) {
1301 		return -EBUSY;
1302 	}
1303 
1304 	if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) {
1305 		SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num);
1306 		return -ENODEV;
1307 	}
1308 
1309 	assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY);
1310 
1311 	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_param_changed,
1312 				       NULL, (void *)(uintptr_t)scsi_tgt_num);
1313 	return 0;
1314 }
1315 
1316 static void
1317 free_task_pool(struct spdk_vhost_scsi_session *svsession)
1318 {
1319 	struct spdk_vhost_session *vsession = &svsession->vsession;
1320 	struct spdk_vhost_virtqueue *vq;
1321 	uint16_t i;
1322 
1323 	for (i = 0; i < vsession->max_queues; i++) {
1324 		vq = &vsession->virtqueue[i];
1325 		if (vq->tasks == NULL) {
1326 			continue;
1327 		}
1328 
1329 		spdk_free(vq->tasks);
1330 		vq->tasks = NULL;
1331 	}
1332 }
1333 
1334 static int
1335 alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
1336 {
1337 	struct spdk_vhost_session *vsession = &svsession->vsession;
1338 	struct spdk_vhost_virtqueue *vq;
1339 	struct spdk_vhost_scsi_task *task;
1340 	uint32_t task_cnt;
1341 	uint16_t i;
1342 	uint32_t j;
1343 
1344 	for (i = 0; i < vsession->max_queues; i++) {
1345 		vq = &vsession->virtqueue[i];
1346 		if (vq->vring.desc == NULL) {
1347 			continue;
1348 		}
1349 
1350 		task_cnt = vq->vring.size;
1351 		if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
1352 			/* sanity check */
1353 			SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
1354 				    vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
1355 			free_task_pool(svsession);
1356 			return -1;
1357 		}
1358 		vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_scsi_task) * task_cnt,
1359 					 SPDK_CACHE_LINE_SIZE, NULL,
1360 					 SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
1361 		if (vq->tasks == NULL) {
1362 			SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
1363 				    vsession->name, task_cnt, i);
1364 			free_task_pool(svsession);
1365 			return -1;
1366 		}
1367 
1368 		for (j = 0; j < task_cnt; j++) {
1369 			task = &((struct spdk_vhost_scsi_task *)vq->tasks)[j];
1370 			task->svsession = svsession;
1371 			task->vq = vq;
1372 			task->req_idx = j;
1373 		}
1374 	}
1375 
1376 	return 0;
1377 }
1378 
1379 static int
1380 vhost_scsi_start_cb(struct spdk_vhost_dev *vdev,
1381 		    struct spdk_vhost_session *vsession, void *unused)
1382 {
1383 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1384 	struct spdk_vhost_scsi_dev *svdev = svsession->svdev;
1385 	struct spdk_scsi_dev_vhost_state *state;
1386 	uint32_t i;
1387 	int rc;
1388 
1389 	/* validate all I/O queues are in a contiguous index range */
1390 	for (i = VIRTIO_SCSI_REQUESTQ; i < vsession->max_queues; i++) {
1391 		if (vsession->virtqueue[i].vring.desc == NULL) {
1392 			SPDK_ERRLOG("%s: queue %"PRIu32" is empty\n", vsession->name, i);
1393 			rc = -1;
1394 			goto out;
1395 		}
1396 	}
1397 
1398 	rc = alloc_task_pool(svsession);
1399 	if (rc != 0) {
1400 		SPDK_ERRLOG("%s: failed to alloc task pool.\n", vsession->name);
1401 		goto out;
1402 	}
1403 
1404 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1405 		state = &svdev->scsi_dev_state[i];
1406 		if (state->dev == NULL || state->status == VHOST_SCSI_DEV_REMOVING) {
1407 			continue;
1408 		}
1409 
1410 		assert(svsession->scsi_dev_state[i].status == VHOST_SCSI_DEV_EMPTY);
1411 		svsession->scsi_dev_state[i].dev = state->dev;
1412 		svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_PRESENT;
1413 		rc = spdk_scsi_dev_allocate_io_channels(state->dev);
1414 		if (rc != 0) {
1415 			SPDK_ERRLOG("%s: failed to alloc io_channel for SCSI target %"PRIu32"\n",
1416 				    vsession->name, i);
1417 			/* unset the SCSI target so that all I/O to it will be rejected */
1418 			svsession->scsi_dev_state[i].dev = NULL;
1419 			/* set EMPTY state so that we won't reply with SCSI hotremove
1420 			 * sense codes - the device hasn't ever been added.
1421 			 */
1422 			svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_EMPTY;
1423 			continue;
1424 		}
1425 	}
1426 	SPDK_INFOLOG(vhost, "%s: started poller on lcore %d\n",
1427 		     vsession->name, spdk_env_get_current_core());
1428 
1429 	svsession->requestq_poller = SPDK_POLLER_REGISTER(vdev_worker, svsession, 0);
1430 	svsession->mgmt_poller = SPDK_POLLER_REGISTER(vdev_mgmt_worker, svsession,
1431 				 MGMT_POLL_PERIOD_US);
1432 out:
1433 	vhost_user_session_start_done(vsession, rc);
1434 	return rc;
1435 }
1436 
1437 static int
1438 vhost_scsi_start(struct spdk_vhost_session *vsession)
1439 {
1440 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1441 	struct spdk_vhost_scsi_dev *svdev;
1442 
1443 	svdev = to_scsi_dev(vsession->vdev);
1444 	assert(svdev != NULL);
1445 	svsession->svdev = svdev;
1446 
1447 	return vhost_user_session_send_event(vsession, vhost_scsi_start_cb,
1448 					     3, "start session");
1449 }
1450 
1451 static int
1452 destroy_session_poller_cb(void *arg)
1453 {
1454 	struct spdk_vhost_scsi_session *svsession = arg;
1455 	struct spdk_vhost_session *vsession = &svsession->vsession;
1456 	struct spdk_scsi_dev_session_state *state;
1457 	uint32_t i;
1458 
1459 	if (vsession->task_cnt > 0 || spdk_vhost_trylock() != 0) {
1460 		assert(vsession->stop_retry_count > 0);
1461 		vsession->stop_retry_count--;
1462 		if (vsession->stop_retry_count == 0) {
1463 			SPDK_ERRLOG("%s: Timedout when destroy session (task_cnt %d)\n", vsession->name,
1464 				    vsession->task_cnt);
1465 			spdk_poller_unregister(&svsession->stop_poller);
1466 			vhost_user_session_stop_done(vsession, -ETIMEDOUT);
1467 		}
1468 
1469 		return SPDK_POLLER_BUSY;
1470 	}
1471 
1472 	for (i = 0; i < vsession->max_queues; i++) {
1473 		vhost_vq_used_signal(vsession, &vsession->virtqueue[i]);
1474 	}
1475 
1476 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1477 		enum spdk_scsi_dev_vhost_status prev_status;
1478 
1479 		state = &svsession->scsi_dev_state[i];
1480 		/* clear the REMOVED status so that we won't send hotremove events anymore */
1481 		prev_status = state->status;
1482 		state->status = VHOST_SCSI_DEV_EMPTY;
1483 		if (state->dev == NULL) {
1484 			continue;
1485 		}
1486 
1487 		spdk_scsi_dev_free_io_channels(state->dev);
1488 
1489 		state->dev = NULL;
1490 
1491 		if (prev_status == VHOST_SCSI_DEV_REMOVING) {
1492 			/* try to detach it globally */
1493 			vhost_user_dev_foreach_session(vsession->vdev,
1494 						       vhost_scsi_session_process_removed,
1495 						       vhost_scsi_dev_process_removed_cpl_cb,
1496 						       (void *)(uintptr_t)i);
1497 		}
1498 	}
1499 
1500 	SPDK_INFOLOG(vhost, "%s: stopping poller on lcore %d\n",
1501 		     vsession->name, spdk_env_get_current_core());
1502 
1503 	free_task_pool(svsession);
1504 
1505 	spdk_poller_unregister(&svsession->stop_poller);
1506 	vhost_user_session_stop_done(vsession, 0);
1507 
1508 	spdk_vhost_unlock();
1509 	return SPDK_POLLER_BUSY;
1510 }
1511 
1512 static int
1513 vhost_scsi_stop_cb(struct spdk_vhost_dev *vdev,
1514 		   struct spdk_vhost_session *vsession, void *unused)
1515 {
1516 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1517 
1518 	/* Stop receiving new I/O requests */
1519 	spdk_poller_unregister(&svsession->requestq_poller);
1520 
1521 	/* Stop receiving controlq requests, also stop processing the
1522 	 * asynchronous hotremove events. All the remaining events
1523 	 * will be finalized by the stop_poller below.
1524 	 */
1525 	spdk_poller_unregister(&svsession->mgmt_poller);
1526 
1527 	/* vhost_user_session_send_event timeout is 3 seconds, here set retry within 4 seconds */
1528 	svsession->vsession.stop_retry_count = 4000;
1529 
1530 	/* Wait for all pending I/Os to complete, then process all the
1531 	 * remaining hotremove events one last time.
1532 	 */
1533 	svsession->stop_poller = SPDK_POLLER_REGISTER(destroy_session_poller_cb,
1534 				 svsession, 1000);
1535 
1536 	return 0;
1537 }
1538 
1539 static int
1540 vhost_scsi_stop(struct spdk_vhost_session *vsession)
1541 {
1542 	return vhost_user_session_send_event(vsession, vhost_scsi_stop_cb,
1543 					     3, "stop session");
1544 }
1545 
1546 static void
1547 vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
1548 {
1549 	struct spdk_scsi_dev *sdev;
1550 	struct spdk_scsi_lun *lun;
1551 	uint32_t dev_idx;
1552 
1553 	assert(vdev != NULL);
1554 	spdk_json_write_named_array_begin(w, "scsi");
1555 	for (dev_idx = 0; dev_idx < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; dev_idx++) {
1556 		sdev = spdk_vhost_scsi_dev_get_tgt(vdev, dev_idx);
1557 		if (!sdev) {
1558 			continue;
1559 		}
1560 
1561 		spdk_json_write_object_begin(w);
1562 
1563 		spdk_json_write_named_uint32(w, "scsi_dev_num", dev_idx);
1564 
1565 		spdk_json_write_named_uint32(w, "id", spdk_scsi_dev_get_id(sdev));
1566 
1567 		spdk_json_write_named_string(w, "target_name", spdk_scsi_dev_get_name(sdev));
1568 
1569 		spdk_json_write_named_array_begin(w, "luns");
1570 
1571 		for (lun = spdk_scsi_dev_get_first_lun(sdev); lun != NULL;
1572 		     lun = spdk_scsi_dev_get_next_lun(lun)) {
1573 			spdk_json_write_object_begin(w);
1574 
1575 			spdk_json_write_named_int32(w, "id", spdk_scsi_lun_get_id(lun));
1576 
1577 			spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun));
1578 
1579 			spdk_json_write_object_end(w);
1580 		}
1581 
1582 		spdk_json_write_array_end(w);
1583 		spdk_json_write_object_end(w);
1584 	}
1585 
1586 	spdk_json_write_array_end(w);
1587 }
1588 
1589 static void
1590 vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
1591 {
1592 	struct spdk_scsi_dev *scsi_dev;
1593 	struct spdk_scsi_lun *lun;
1594 	uint32_t i;
1595 
1596 	spdk_json_write_object_begin(w);
1597 	spdk_json_write_named_string(w, "method", "vhost_create_scsi_controller");
1598 
1599 	spdk_json_write_named_object_begin(w, "params");
1600 	spdk_json_write_named_string(w, "ctrlr", vdev->name);
1601 	spdk_json_write_named_string(w, "cpumask",
1602 				     spdk_cpuset_fmt(spdk_thread_get_cpumask(vdev->thread)));
1603 	spdk_json_write_object_end(w);
1604 
1605 	spdk_json_write_object_end(w);
1606 
1607 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1608 		scsi_dev = spdk_vhost_scsi_dev_get_tgt(vdev, i);
1609 		if (scsi_dev == NULL) {
1610 			continue;
1611 		}
1612 
1613 		lun = spdk_scsi_dev_get_lun(scsi_dev, 0);
1614 		assert(lun != NULL);
1615 
1616 		spdk_json_write_object_begin(w);
1617 		spdk_json_write_named_string(w, "method", "vhost_scsi_controller_add_target");
1618 
1619 		spdk_json_write_named_object_begin(w, "params");
1620 		spdk_json_write_named_string(w, "ctrlr", vdev->name);
1621 		spdk_json_write_named_uint32(w, "scsi_target_num", i);
1622 
1623 		spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun));
1624 		spdk_json_write_object_end(w);
1625 
1626 		spdk_json_write_object_end(w);
1627 	}
1628 }
1629 
1630 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi)
1631 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi_queue)
1632 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi_data)
1633