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