xref: /spdk/lib/vhost/vhost_scsi.c (revision 1eca87c39c854777f96a08d78c0c7fa1b76aae67)
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 
889 	if (rc) {
890 		free(svdev);
891 		spdk_vhost_unlock();
892 		return rc;
893 	}
894 
895 	svdev->registered = true;
896 
897 	spdk_vhost_unlock();
898 	return rc;
899 }
900 
901 static int
902 vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev)
903 {
904 	struct spdk_vhost_scsi_dev *svdev = to_scsi_dev(vdev);
905 	struct spdk_vhost_user_dev *user_dev = vdev->ctxt;
906 	int rc, i;
907 
908 	if (user_dev->pending_async_op_num) {
909 		return -EBUSY;
910 	}
911 
912 	assert(svdev != NULL);
913 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) {
914 		if (svdev->scsi_dev_state[i].dev) {
915 			if (vdev->registered) {
916 				SPDK_ERRLOG("%s: SCSI target %d is still present.\n", vdev->name, i);
917 				return -EBUSY;
918 			}
919 
920 			rc = spdk_vhost_scsi_dev_remove_tgt(vdev, i, NULL, NULL);
921 			if (rc != 0) {
922 				SPDK_ERRLOG("%s: failed to force-remove target %d\n", vdev->name, i);
923 				return rc;
924 			}
925 		}
926 	}
927 
928 	rc = vhost_dev_unregister(vdev);
929 	if (rc != 0) {
930 		return rc;
931 	}
932 	svdev->registered = false;
933 
934 	if (svdev->ref == 0) {
935 		free(svdev);
936 	}
937 
938 	return 0;
939 }
940 
941 struct spdk_scsi_dev *
942 spdk_vhost_scsi_dev_get_tgt(struct spdk_vhost_dev *vdev, uint8_t num)
943 {
944 	struct spdk_vhost_scsi_dev *svdev;
945 
946 	assert(num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
947 	svdev = to_scsi_dev(vdev);
948 	assert(svdev != NULL);
949 	if (svdev->scsi_dev_state[num].status != VHOST_SCSI_DEV_PRESENT) {
950 		return NULL;
951 	}
952 
953 	assert(svdev->scsi_dev_state[num].dev != NULL);
954 	return svdev->scsi_dev_state[num].dev;
955 }
956 
957 static unsigned
958 get_scsi_dev_num(const struct spdk_vhost_scsi_dev *svdev,
959 		 const struct spdk_scsi_lun *lun)
960 {
961 	const struct spdk_scsi_dev *scsi_dev;
962 	unsigned scsi_dev_num;
963 
964 	assert(lun != NULL);
965 	assert(svdev != NULL);
966 	scsi_dev = spdk_scsi_lun_get_dev(lun);
967 	for (scsi_dev_num = 0; scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_dev_num++) {
968 		if (svdev->scsi_dev_state[scsi_dev_num].dev == scsi_dev) {
969 			break;
970 		}
971 	}
972 
973 	return scsi_dev_num;
974 }
975 
976 static void
977 vhost_scsi_lun_resize(const struct spdk_scsi_lun *lun, void *arg)
978 {
979 	struct spdk_vhost_scsi_dev *svdev = arg;
980 	unsigned scsi_dev_num;
981 
982 	scsi_dev_num = get_scsi_dev_num(svdev, lun);
983 	if (scsi_dev_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
984 		/* The entire device has been already removed. */
985 		return;
986 	}
987 
988 	vhost_scsi_dev_param_changed(&svdev->vdev, scsi_dev_num);
989 }
990 
991 static void
992 vhost_scsi_lun_hotremove(const struct spdk_scsi_lun *lun, void *arg)
993 {
994 	struct spdk_vhost_scsi_dev *svdev = arg;
995 	unsigned scsi_dev_num;
996 
997 	scsi_dev_num = get_scsi_dev_num(svdev, lun);
998 	if (scsi_dev_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
999 		/* The entire device has been already removed. */
1000 		return;
1001 	}
1002 
1003 	/* remove entire device */
1004 	spdk_vhost_scsi_dev_remove_tgt(&svdev->vdev, scsi_dev_num, NULL, NULL);
1005 }
1006 
1007 static void
1008 vhost_scsi_dev_add_tgt_cpl_cb(struct spdk_vhost_dev *vdev, void *ctx)
1009 {
1010 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
1011 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
1012 					    struct spdk_vhost_scsi_dev, vdev);
1013 	struct spdk_scsi_dev_vhost_state *vhost_sdev;
1014 
1015 	vhost_sdev = &svdev->scsi_dev_state[scsi_tgt_num];
1016 
1017 	/* All sessions have added the target */
1018 	assert(vhost_sdev->status == VHOST_SCSI_DEV_ADDING);
1019 	vhost_sdev->status = VHOST_SCSI_DEV_PRESENT;
1020 	svdev->ref++;
1021 }
1022 
1023 static int
1024 vhost_scsi_session_add_tgt(struct spdk_vhost_dev *vdev,
1025 			   struct spdk_vhost_session *vsession, void *ctx)
1026 {
1027 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
1028 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
1029 	struct spdk_scsi_dev_session_state *session_sdev = &svsession->scsi_dev_state[scsi_tgt_num];
1030 	struct spdk_scsi_dev_vhost_state *vhost_sdev;
1031 	int rc;
1032 
1033 	if (!vsession->started || session_sdev->dev != NULL) {
1034 		/* Nothing to do. */
1035 		return 0;
1036 	}
1037 
1038 	vhost_sdev = &svsession->svdev->scsi_dev_state[scsi_tgt_num];
1039 	session_sdev->dev = vhost_sdev->dev;
1040 	session_sdev->status = VHOST_SCSI_DEV_PRESENT;
1041 
1042 	rc = spdk_scsi_dev_allocate_io_channels(svsession->scsi_dev_state[scsi_tgt_num].dev);
1043 	if (rc != 0) {
1044 		SPDK_ERRLOG("%s: Couldn't allocate io channel for SCSI target %u.\n",
1045 			    vsession->name, scsi_tgt_num);
1046 
1047 		/* unset the SCSI target so that all I/O to it will be rejected */
1048 		session_sdev->dev = NULL;
1049 		/* Set status to EMPTY so that we won't reply with SCSI hotremove
1050 		 * sense codes - the device hasn't ever been added.
1051 		 */
1052 		session_sdev->status = VHOST_SCSI_DEV_EMPTY;
1053 
1054 		/* Return with no error. We'll continue allocating io_channels for
1055 		 * other sessions on this device in hopes they succeed. The sessions
1056 		 * that failed to allocate io_channels simply won't be able to
1057 		 * detect the SCSI target, nor do any I/O to it.
1058 		 */
1059 		return 0;
1060 	}
1061 
1062 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) {
1063 		eventq_enqueue(svsession, scsi_tgt_num,
1064 			       VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_RESCAN);
1065 	} else {
1066 		SPDK_NOTICELOG("%s: driver does not support hotplug. "
1067 			       "Please restart it or perform a rescan.\n",
1068 			       vsession->name);
1069 	}
1070 
1071 	return 0;
1072 }
1073 
1074 int
1075 spdk_vhost_scsi_dev_add_tgt(struct spdk_vhost_dev *vdev, int scsi_tgt_num,
1076 			    const char *bdev_name)
1077 {
1078 	struct spdk_vhost_scsi_dev *svdev;
1079 	struct spdk_scsi_dev_vhost_state *state;
1080 	char target_name[SPDK_SCSI_DEV_MAX_NAME];
1081 	int lun_id_list[1];
1082 	const char *bdev_names_list[1];
1083 
1084 	svdev = to_scsi_dev(vdev);
1085 	if (!svdev) {
1086 		SPDK_ERRLOG("Before adding a SCSI target, there should be a SCSI device.");
1087 		return -EINVAL;
1088 	}
1089 
1090 	if (scsi_tgt_num < 0) {
1091 		for (scsi_tgt_num = 0; scsi_tgt_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_tgt_num++) {
1092 			if (svdev->scsi_dev_state[scsi_tgt_num].dev == NULL) {
1093 				break;
1094 			}
1095 		}
1096 
1097 		if (scsi_tgt_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1098 			SPDK_ERRLOG("%s: all SCSI target slots are already in use.\n", vdev->name);
1099 			return -ENOSPC;
1100 		}
1101 	} else {
1102 		if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1103 			SPDK_ERRLOG("%s: SCSI target number is too big (got %d, max %d), started from 0.\n",
1104 				    vdev->name, scsi_tgt_num, SPDK_VHOST_SCSI_CTRLR_MAX_DEVS - 1);
1105 			return -EINVAL;
1106 		}
1107 	}
1108 
1109 	if (bdev_name == NULL) {
1110 		SPDK_ERRLOG("No lun name specified\n");
1111 		return -EINVAL;
1112 	}
1113 
1114 	state = &svdev->scsi_dev_state[scsi_tgt_num];
1115 	if (state->dev != NULL) {
1116 		SPDK_ERRLOG("%s: SCSI target %u already occupied\n", vdev->name, scsi_tgt_num);
1117 		return -EEXIST;
1118 	}
1119 
1120 	/*
1121 	 * At this stage only one LUN per target
1122 	 */
1123 	snprintf(target_name, sizeof(target_name), "Target %u", scsi_tgt_num);
1124 	lun_id_list[0] = 0;
1125 	bdev_names_list[0] = (char *)bdev_name;
1126 
1127 	state->status = VHOST_SCSI_DEV_ADDING;
1128 	state->dev = spdk_scsi_dev_construct_ext(target_name, bdev_names_list, lun_id_list, 1,
1129 			SPDK_SPC_PROTOCOL_IDENTIFIER_SAS,
1130 			vhost_scsi_lun_resize, svdev,
1131 			vhost_scsi_lun_hotremove, svdev);
1132 
1133 	if (state->dev == NULL) {
1134 		state->status = VHOST_SCSI_DEV_EMPTY;
1135 		SPDK_ERRLOG("%s: couldn't create SCSI target %u using bdev '%s'\n",
1136 			    vdev->name, scsi_tgt_num, bdev_name);
1137 		return -EINVAL;
1138 	}
1139 	spdk_scsi_dev_add_port(state->dev, 0, "vhost");
1140 
1141 	SPDK_INFOLOG(vhost, "%s: added SCSI target %u using bdev '%s'\n",
1142 		     vdev->name, scsi_tgt_num, bdev_name);
1143 
1144 	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_add_tgt,
1145 				       vhost_scsi_dev_add_tgt_cpl_cb,
1146 				       (void *)(uintptr_t)scsi_tgt_num);
1147 	return scsi_tgt_num;
1148 }
1149 
1150 struct scsi_tgt_hotplug_ctx {
1151 	unsigned scsi_tgt_num;
1152 	bool async_fini;
1153 };
1154 
1155 static void
1156 vhost_scsi_dev_remove_tgt_cpl_cb(struct spdk_vhost_dev *vdev, void *_ctx)
1157 {
1158 	struct scsi_tgt_hotplug_ctx *ctx = _ctx;
1159 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
1160 					    struct spdk_vhost_scsi_dev, vdev);
1161 
1162 	if (!ctx->async_fini) {
1163 		/* there aren't any active sessions, so remove the dev and exit */
1164 		remove_scsi_tgt(svdev, ctx->scsi_tgt_num);
1165 	}
1166 
1167 	free(ctx);
1168 }
1169 
1170 static int
1171 vhost_scsi_session_remove_tgt(struct spdk_vhost_dev *vdev,
1172 			      struct spdk_vhost_session *vsession, void *_ctx)
1173 {
1174 	struct scsi_tgt_hotplug_ctx *ctx = _ctx;
1175 	unsigned scsi_tgt_num = ctx->scsi_tgt_num;
1176 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
1177 	struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num];
1178 
1179 	if (!vsession->started || state->dev == NULL) {
1180 		/* Nothing to do */
1181 		return 0;
1182 	}
1183 
1184 	/* Mark the target for removal */
1185 	assert(state->status == VHOST_SCSI_DEV_PRESENT);
1186 	state->status = VHOST_SCSI_DEV_REMOVING;
1187 
1188 	/* Send a hotremove virtio event */
1189 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) {
1190 		eventq_enqueue(svsession, scsi_tgt_num,
1191 			       VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_REMOVED);
1192 	}
1193 
1194 	/* Wait for the session's management poller to remove the target after
1195 	 * all its pending I/O has finished.
1196 	 */
1197 	ctx->async_fini = true;
1198 	return 0;
1199 }
1200 
1201 int
1202 spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num,
1203 			       spdk_vhost_event_fn cb_fn, void *cb_arg)
1204 {
1205 	struct spdk_vhost_scsi_dev *svdev;
1206 	struct spdk_scsi_dev_vhost_state *scsi_dev_state;
1207 	struct scsi_tgt_hotplug_ctx *ctx;
1208 
1209 	if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1210 		SPDK_ERRLOG("%s: invalid SCSI target number %d\n", vdev->name, scsi_tgt_num);
1211 		return -EINVAL;
1212 	}
1213 
1214 	svdev = to_scsi_dev(vdev);
1215 	if (!svdev) {
1216 		SPDK_ERRLOG("An invalid SCSI device that removing from a SCSI target.");
1217 		return -EINVAL;
1218 	}
1219 
1220 	scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num];
1221 
1222 	if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) {
1223 		return -EBUSY;
1224 	}
1225 
1226 	if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) {
1227 		SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num);
1228 		return -ENODEV;
1229 	}
1230 
1231 	assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY);
1232 	ctx = calloc(1, sizeof(*ctx));
1233 	if (ctx == NULL) {
1234 		SPDK_ERRLOG("calloc failed\n");
1235 		return -ENOMEM;
1236 	}
1237 
1238 	ctx->scsi_tgt_num = scsi_tgt_num;
1239 	ctx->async_fini = false;
1240 
1241 	scsi_dev_state->remove_cb = cb_fn;
1242 	scsi_dev_state->remove_ctx = cb_arg;
1243 	scsi_dev_state->status = VHOST_SCSI_DEV_REMOVING;
1244 
1245 	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_remove_tgt,
1246 				       vhost_scsi_dev_remove_tgt_cpl_cb, ctx);
1247 	return 0;
1248 }
1249 
1250 static int
1251 vhost_scsi_session_param_changed(struct spdk_vhost_dev *vdev,
1252 				 struct spdk_vhost_session *vsession, void *ctx)
1253 {
1254 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
1255 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
1256 	struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num];
1257 
1258 	if (!vsession->started || state->dev == NULL) {
1259 		/* Nothing to do */
1260 		return 0;
1261 	}
1262 
1263 	/* Send a parameter change virtio event */
1264 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_CHANGE)) {
1265 		/*
1266 		 * virtio 1.0 spec says:
1267 		 * By sending this event, the device signals a change in the configuration
1268 		 * parameters of a logical unit, for example the capacity or cache mode.
1269 		 * event is set to VIRTIO_SCSI_T_PARAM_CHANGE. lun addresses a logical unit
1270 		 * in the SCSI host. The same event SHOULD also be reported as a unit
1271 		 * attention condition. reason contains the additional sense code and
1272 		 * additional sense code qualifier, respectively in bits 0…7 and 8…15.
1273 		 * Note: For example, a change in * capacity will be reported as asc
1274 		 * 0x2a, ascq 0x09 (CAPACITY DATA HAS CHANGED).
1275 		 */
1276 		eventq_enqueue(svsession, scsi_tgt_num, VIRTIO_SCSI_T_PARAM_CHANGE, 0x2a | (0x09 << 8));
1277 	}
1278 
1279 	return 0;
1280 }
1281 
1282 static int
1283 vhost_scsi_dev_param_changed(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num)
1284 {
1285 	struct spdk_vhost_scsi_dev *svdev;
1286 	struct spdk_scsi_dev_vhost_state *scsi_dev_state;
1287 
1288 	if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1289 		SPDK_ERRLOG("%s: invalid SCSI target number %d\n", vdev->name, scsi_tgt_num);
1290 		return -EINVAL;
1291 	}
1292 
1293 	svdev = to_scsi_dev(vdev);
1294 	if (!svdev) {
1295 		SPDK_ERRLOG("An invalid SCSI device that removing from a SCSI target.");
1296 		return -EINVAL;
1297 	}
1298 
1299 	scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num];
1300 
1301 	if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) {
1302 		return -EBUSY;
1303 	}
1304 
1305 	if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) {
1306 		SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num);
1307 		return -ENODEV;
1308 	}
1309 
1310 	assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY);
1311 
1312 	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_param_changed,
1313 				       NULL, (void *)(uintptr_t)scsi_tgt_num);
1314 	return 0;
1315 }
1316 
1317 static void
1318 free_task_pool(struct spdk_vhost_scsi_session *svsession)
1319 {
1320 	struct spdk_vhost_session *vsession = &svsession->vsession;
1321 	struct spdk_vhost_virtqueue *vq;
1322 	uint16_t i;
1323 
1324 	for (i = 0; i < vsession->max_queues; i++) {
1325 		vq = &vsession->virtqueue[i];
1326 		if (vq->tasks == NULL) {
1327 			continue;
1328 		}
1329 
1330 		spdk_free(vq->tasks);
1331 		vq->tasks = NULL;
1332 	}
1333 }
1334 
1335 static int
1336 alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
1337 {
1338 	struct spdk_vhost_session *vsession = &svsession->vsession;
1339 	struct spdk_vhost_virtqueue *vq;
1340 	struct spdk_vhost_scsi_task *task;
1341 	uint32_t task_cnt;
1342 	uint16_t i;
1343 	uint32_t j;
1344 
1345 	for (i = 0; i < vsession->max_queues; i++) {
1346 		vq = &vsession->virtqueue[i];
1347 		if (vq->vring.desc == NULL) {
1348 			continue;
1349 		}
1350 
1351 		task_cnt = vq->vring.size;
1352 		if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
1353 			/* sanity check */
1354 			SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
1355 				    vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
1356 			free_task_pool(svsession);
1357 			return -1;
1358 		}
1359 		vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_scsi_task) * task_cnt,
1360 					 SPDK_CACHE_LINE_SIZE, NULL,
1361 					 SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
1362 		if (vq->tasks == NULL) {
1363 			SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
1364 				    vsession->name, task_cnt, i);
1365 			free_task_pool(svsession);
1366 			return -1;
1367 		}
1368 
1369 		for (j = 0; j < task_cnt; j++) {
1370 			task = &((struct spdk_vhost_scsi_task *)vq->tasks)[j];
1371 			task->svsession = svsession;
1372 			task->vq = vq;
1373 			task->req_idx = j;
1374 		}
1375 	}
1376 
1377 	return 0;
1378 }
1379 
1380 static int
1381 vhost_scsi_start_cb(struct spdk_vhost_dev *vdev,
1382 		    struct spdk_vhost_session *vsession, void *unused)
1383 {
1384 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1385 	struct spdk_vhost_scsi_dev *svdev = svsession->svdev;
1386 	struct spdk_scsi_dev_vhost_state *state;
1387 	uint32_t i;
1388 	int rc;
1389 
1390 	/* validate all I/O queues are in a contiguous index range */
1391 	for (i = VIRTIO_SCSI_REQUESTQ; i < vsession->max_queues; i++) {
1392 		if (vsession->virtqueue[i].vring.desc == NULL) {
1393 			SPDK_ERRLOG("%s: queue %"PRIu32" is empty\n", vsession->name, i);
1394 			rc = -1;
1395 			goto out;
1396 		}
1397 	}
1398 
1399 	rc = alloc_task_pool(svsession);
1400 	if (rc != 0) {
1401 		SPDK_ERRLOG("%s: failed to alloc task pool.\n", vsession->name);
1402 		goto out;
1403 	}
1404 
1405 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1406 		state = &svdev->scsi_dev_state[i];
1407 		if (state->dev == NULL || state->status == VHOST_SCSI_DEV_REMOVING) {
1408 			continue;
1409 		}
1410 
1411 		assert(svsession->scsi_dev_state[i].status == VHOST_SCSI_DEV_EMPTY);
1412 		svsession->scsi_dev_state[i].dev = state->dev;
1413 		svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_PRESENT;
1414 		rc = spdk_scsi_dev_allocate_io_channels(state->dev);
1415 		if (rc != 0) {
1416 			SPDK_ERRLOG("%s: failed to alloc io_channel for SCSI target %"PRIu32"\n",
1417 				    vsession->name, i);
1418 			/* unset the SCSI target so that all I/O to it will be rejected */
1419 			svsession->scsi_dev_state[i].dev = NULL;
1420 			/* set EMPTY state so that we won't reply with SCSI hotremove
1421 			 * sense codes - the device hasn't ever been added.
1422 			 */
1423 			svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_EMPTY;
1424 			continue;
1425 		}
1426 	}
1427 	SPDK_INFOLOG(vhost, "%s: started poller on lcore %d\n",
1428 		     vsession->name, spdk_env_get_current_core());
1429 
1430 	svsession->requestq_poller = SPDK_POLLER_REGISTER(vdev_worker, svsession, 0);
1431 	svsession->mgmt_poller = SPDK_POLLER_REGISTER(vdev_mgmt_worker, svsession,
1432 				 MGMT_POLL_PERIOD_US);
1433 out:
1434 	vhost_user_session_start_done(vsession, rc);
1435 	return rc;
1436 }
1437 
1438 static int
1439 vhost_scsi_start(struct spdk_vhost_session *vsession)
1440 {
1441 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1442 	struct spdk_vhost_scsi_dev *svdev;
1443 
1444 	svdev = to_scsi_dev(vsession->vdev);
1445 	assert(svdev != NULL);
1446 	svsession->svdev = svdev;
1447 
1448 	return vhost_user_session_send_event(vsession, vhost_scsi_start_cb,
1449 					     3, "start session");
1450 }
1451 
1452 static int
1453 destroy_session_poller_cb(void *arg)
1454 {
1455 	struct spdk_vhost_scsi_session *svsession = arg;
1456 	struct spdk_vhost_session *vsession = &svsession->vsession;
1457 	struct spdk_scsi_dev_session_state *state;
1458 	uint32_t i;
1459 
1460 	if (vsession->task_cnt > 0 || spdk_vhost_trylock() != 0) {
1461 		assert(vsession->stop_retry_count > 0);
1462 		vsession->stop_retry_count--;
1463 		if (vsession->stop_retry_count == 0) {
1464 			SPDK_ERRLOG("%s: Timedout when destroy session (task_cnt %d)\n", vsession->name,
1465 				    vsession->task_cnt);
1466 			spdk_poller_unregister(&svsession->stop_poller);
1467 			vhost_user_session_stop_done(vsession, -ETIMEDOUT);
1468 		}
1469 
1470 		return SPDK_POLLER_BUSY;
1471 	}
1472 
1473 	for (i = 0; i < vsession->max_queues; i++) {
1474 		vhost_vq_used_signal(vsession, &vsession->virtqueue[i]);
1475 	}
1476 
1477 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1478 		enum spdk_scsi_dev_vhost_status prev_status;
1479 
1480 		state = &svsession->scsi_dev_state[i];
1481 		/* clear the REMOVED status so that we won't send hotremove events anymore */
1482 		prev_status = state->status;
1483 		state->status = VHOST_SCSI_DEV_EMPTY;
1484 		if (state->dev == NULL) {
1485 			continue;
1486 		}
1487 
1488 		spdk_scsi_dev_free_io_channels(state->dev);
1489 
1490 		state->dev = NULL;
1491 
1492 		if (prev_status == VHOST_SCSI_DEV_REMOVING) {
1493 			/* try to detach it globally */
1494 			vhost_user_dev_foreach_session(vsession->vdev,
1495 						       vhost_scsi_session_process_removed,
1496 						       vhost_scsi_dev_process_removed_cpl_cb,
1497 						       (void *)(uintptr_t)i);
1498 		}
1499 	}
1500 
1501 	SPDK_INFOLOG(vhost, "%s: stopping poller on lcore %d\n",
1502 		     vsession->name, spdk_env_get_current_core());
1503 
1504 	free_task_pool(svsession);
1505 
1506 	spdk_poller_unregister(&svsession->stop_poller);
1507 	vhost_user_session_stop_done(vsession, 0);
1508 
1509 	spdk_vhost_unlock();
1510 	return SPDK_POLLER_BUSY;
1511 }
1512 
1513 static int
1514 vhost_scsi_stop_cb(struct spdk_vhost_dev *vdev,
1515 		   struct spdk_vhost_session *vsession, void *unused)
1516 {
1517 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1518 
1519 	/* Stop receiving new I/O requests */
1520 	spdk_poller_unregister(&svsession->requestq_poller);
1521 
1522 	/* Stop receiving controlq requests, also stop processing the
1523 	 * asynchronous hotremove events. All the remaining events
1524 	 * will be finalized by the stop_poller below.
1525 	 */
1526 	spdk_poller_unregister(&svsession->mgmt_poller);
1527 
1528 	/* vhost_user_session_send_event timeout is 3 seconds, here set retry within 4 seconds */
1529 	svsession->vsession.stop_retry_count = 4000;
1530 
1531 	/* Wait for all pending I/Os to complete, then process all the
1532 	 * remaining hotremove events one last time.
1533 	 */
1534 	svsession->stop_poller = SPDK_POLLER_REGISTER(destroy_session_poller_cb,
1535 				 svsession, 1000);
1536 
1537 	return 0;
1538 }
1539 
1540 static int
1541 vhost_scsi_stop(struct spdk_vhost_session *vsession)
1542 {
1543 	return vhost_user_session_send_event(vsession, vhost_scsi_stop_cb,
1544 					     3, "stop session");
1545 }
1546 
1547 static void
1548 vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
1549 {
1550 	struct spdk_scsi_dev *sdev;
1551 	struct spdk_scsi_lun *lun;
1552 	uint32_t dev_idx;
1553 
1554 	assert(vdev != NULL);
1555 	spdk_json_write_named_array_begin(w, "scsi");
1556 	for (dev_idx = 0; dev_idx < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; dev_idx++) {
1557 		sdev = spdk_vhost_scsi_dev_get_tgt(vdev, dev_idx);
1558 		if (!sdev) {
1559 			continue;
1560 		}
1561 
1562 		spdk_json_write_object_begin(w);
1563 
1564 		spdk_json_write_named_uint32(w, "scsi_dev_num", dev_idx);
1565 
1566 		spdk_json_write_named_uint32(w, "id", spdk_scsi_dev_get_id(sdev));
1567 
1568 		spdk_json_write_named_string(w, "target_name", spdk_scsi_dev_get_name(sdev));
1569 
1570 		spdk_json_write_named_array_begin(w, "luns");
1571 
1572 		for (lun = spdk_scsi_dev_get_first_lun(sdev); lun != NULL;
1573 		     lun = spdk_scsi_dev_get_next_lun(lun)) {
1574 			spdk_json_write_object_begin(w);
1575 
1576 			spdk_json_write_named_int32(w, "id", spdk_scsi_lun_get_id(lun));
1577 
1578 			spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun));
1579 
1580 			spdk_json_write_object_end(w);
1581 		}
1582 
1583 		spdk_json_write_array_end(w);
1584 		spdk_json_write_object_end(w);
1585 	}
1586 
1587 	spdk_json_write_array_end(w);
1588 }
1589 
1590 static void
1591 vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
1592 {
1593 	struct spdk_scsi_dev *scsi_dev;
1594 	struct spdk_scsi_lun *lun;
1595 	uint32_t i;
1596 
1597 	spdk_json_write_object_begin(w);
1598 	spdk_json_write_named_string(w, "method", "vhost_create_scsi_controller");
1599 
1600 	spdk_json_write_named_object_begin(w, "params");
1601 	spdk_json_write_named_string(w, "ctrlr", vdev->name);
1602 	spdk_json_write_named_string(w, "cpumask",
1603 				     spdk_cpuset_fmt(spdk_thread_get_cpumask(vdev->thread)));
1604 	spdk_json_write_object_end(w);
1605 
1606 	spdk_json_write_object_end(w);
1607 
1608 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1609 		scsi_dev = spdk_vhost_scsi_dev_get_tgt(vdev, i);
1610 		if (scsi_dev == NULL) {
1611 			continue;
1612 		}
1613 
1614 		lun = spdk_scsi_dev_get_lun(scsi_dev, 0);
1615 		assert(lun != NULL);
1616 
1617 		spdk_json_write_object_begin(w);
1618 		spdk_json_write_named_string(w, "method", "vhost_scsi_controller_add_target");
1619 
1620 		spdk_json_write_named_object_begin(w, "params");
1621 		spdk_json_write_named_string(w, "ctrlr", vdev->name);
1622 		spdk_json_write_named_uint32(w, "scsi_target_num", i);
1623 
1624 		spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun));
1625 		spdk_json_write_object_end(w);
1626 
1627 		spdk_json_write_object_end(w);
1628 	}
1629 }
1630 
1631 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi)
1632 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi_queue)
1633 SPDK_LOG_REGISTER_COMPONENT(vhost_scsi_data)
1634