xref: /spdk/lib/vhost/vhost_scsi.c (revision 42dba6047b054d9db99f2a78f1b7100a9b3162a1)
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/event.h"
44 #include "spdk/util.h"
45 #include "spdk/likely.h"
46 
47 #include "spdk/vhost.h"
48 #include "vhost_internal.h"
49 
50 /* Features supported by SPDK VHOST lib. */
51 #define SPDK_VHOST_SCSI_FEATURES	(SPDK_VHOST_FEATURES | \
52 					(1ULL << VIRTIO_SCSI_F_INOUT) | \
53 					(1ULL << VIRTIO_SCSI_F_HOTPLUG) | \
54 					(1ULL << VIRTIO_SCSI_F_CHANGE ) | \
55 					(1ULL << VIRTIO_SCSI_F_T10_PI ))
56 
57 /* Features that are specified in VIRTIO SCSI but currently not supported:
58  * - Live migration not supported yet
59  * - T10 PI
60  */
61 #define SPDK_VHOST_SCSI_DISABLED_FEATURES	(SPDK_VHOST_DISABLED_FEATURES | \
62 						(1ULL << VIRTIO_SCSI_F_T10_PI ))
63 
64 #define MGMT_POLL_PERIOD_US (1000 * 5)
65 
66 #define VIRTIO_SCSI_CONTROLQ   0
67 #define VIRTIO_SCSI_EVENTQ   1
68 #define VIRTIO_SCSI_REQUESTQ   2
69 
70 struct spdk_scsi_dev_vhost_state {
71 	struct spdk_scsi_dev *dev;
72 	bool removed;
73 	spdk_vhost_event_fn remove_cb;
74 	void *remove_ctx;
75 };
76 
77 struct spdk_vhost_scsi_dev {
78 	struct spdk_vhost_dev vdev;
79 	struct spdk_scsi_dev_vhost_state scsi_dev_state[SPDK_VHOST_SCSI_CTRLR_MAX_DEVS];
80 } __rte_cache_aligned;
81 
82 struct spdk_vhost_scsi_session {
83 	struct spdk_vhost_session vsession;
84 
85 	struct spdk_vhost_scsi_dev *svdev;
86 	struct spdk_poller *requestq_poller;
87 	struct spdk_poller *mgmt_poller;
88 	struct spdk_vhost_dev_destroy_ctx destroy_ctx;
89 };
90 
91 struct spdk_vhost_scsi_task {
92 	struct spdk_scsi_task	scsi;
93 	struct iovec iovs[SPDK_VHOST_IOVS_MAX];
94 
95 	union {
96 		struct virtio_scsi_cmd_resp *resp;
97 		struct virtio_scsi_ctrl_tmf_resp *tmf_resp;
98 	};
99 
100 	struct spdk_vhost_scsi_session *svsession;
101 	struct spdk_scsi_dev *scsi_dev;
102 
103 	/** Number of bytes that were written. */
104 	uint32_t used_len;
105 
106 	int req_idx;
107 
108 	/* If set, the task is currently used for I/O processing. */
109 	bool used;
110 
111 	struct spdk_vhost_virtqueue *vq;
112 };
113 
114 static int spdk_vhost_scsi_start(struct spdk_vhost_dev *, void *);
115 static int spdk_vhost_scsi_stop(struct spdk_vhost_dev *, void *);
116 static void spdk_vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev,
117 		struct spdk_json_write_ctx *w);
118 static void spdk_vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev,
119 		struct spdk_json_write_ctx *w);
120 static int spdk_vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev);
121 
122 const struct spdk_vhost_dev_backend spdk_vhost_scsi_device_backend = {
123 	.virtio_features = SPDK_VHOST_SCSI_FEATURES,
124 	.disabled_features = SPDK_VHOST_SCSI_DISABLED_FEATURES,
125 	.session_ctx_size = sizeof(struct spdk_vhost_scsi_session) - sizeof(struct spdk_vhost_session),
126 	.start_device =  spdk_vhost_scsi_start,
127 	.stop_device = spdk_vhost_scsi_stop,
128 	.dump_info_json = spdk_vhost_scsi_dump_info_json,
129 	.write_config_json = spdk_vhost_scsi_write_config_json,
130 	.remove_device = spdk_vhost_scsi_dev_remove,
131 };
132 
133 static void
134 spdk_vhost_scsi_task_put(struct spdk_vhost_scsi_task *task)
135 {
136 	spdk_scsi_task_put(&task->scsi);
137 }
138 
139 static void
140 spdk_vhost_scsi_task_free_cb(struct spdk_scsi_task *scsi_task)
141 {
142 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
143 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
144 
145 	assert(vsession->task_cnt > 0);
146 	vsession->task_cnt--;
147 	task->used = false;
148 }
149 
150 static void
151 process_removed_devs(struct spdk_vhost_scsi_dev *svdev)
152 {
153 	struct spdk_scsi_dev *dev;
154 	struct spdk_scsi_dev_vhost_state *state;
155 	int i;
156 
157 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) {
158 		state = &svdev->scsi_dev_state[i];
159 		dev = state->dev;
160 
161 		if (dev && state->removed && !spdk_scsi_dev_has_pending_tasks(dev)) {
162 			spdk_scsi_dev_free_io_channels(dev);
163 			svdev->scsi_dev_state[i].dev = NULL;
164 			spdk_scsi_dev_destruct(dev);
165 			if (state->remove_cb) {
166 				state->remove_cb(&svdev->vdev, state->remove_ctx);
167 				state->remove_cb = NULL;
168 			}
169 			SPDK_INFOLOG(SPDK_LOG_VHOST, "%s: hot-detached device 'Dev %u'.\n",
170 				     svdev->vdev.name, i);
171 		}
172 	}
173 }
174 
175 static void
176 eventq_enqueue(struct spdk_vhost_scsi_session *svsession, unsigned scsi_dev_num,
177 	       uint32_t event, uint32_t reason)
178 {
179 	struct spdk_vhost_session *vsession = &svsession->vsession;
180 	struct spdk_vhost_dev *vdev = vsession->vdev;
181 	struct spdk_vhost_virtqueue *vq;
182 	struct vring_desc *desc, *desc_table;
183 	struct virtio_scsi_event *desc_ev;
184 	uint32_t desc_table_size, req_size = 0;
185 	uint16_t req;
186 	int rc;
187 
188 	assert(scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
189 	vq = &vsession->virtqueue[VIRTIO_SCSI_EVENTQ];
190 
191 	if (spdk_vhost_vq_avail_ring_get(vq, &req, 1) != 1) {
192 		SPDK_ERRLOG("Controller %s: Failed to send virtio event (no avail ring entries?).\n",
193 			    vdev->name);
194 		return;
195 	}
196 
197 	rc = spdk_vhost_vq_get_desc(vsession, vq, req, &desc, &desc_table, &desc_table_size);
198 	if (rc != 0 || desc->len < sizeof(*desc_ev)) {
199 		SPDK_ERRLOG("Controller %s: Invalid eventq descriptor at index %"PRIu16".\n",
200 			    vdev->name, req);
201 		goto out;
202 	}
203 
204 	desc_ev = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(*desc_ev));
205 	if (desc_ev == NULL) {
206 		SPDK_ERRLOG("Controller %s: Eventq descriptor at index %"PRIu16" points to unmapped guest memory address %p.\n",
207 			    vdev->name, req, (void *)(uintptr_t)desc->addr);
208 		goto out;
209 	}
210 
211 	desc_ev->event = event;
212 	desc_ev->lun[0] = 1;
213 	desc_ev->lun[1] = scsi_dev_num;
214 	/* virtio LUN id 0 can refer either to the entire device
215 	 * or actual LUN 0 (the only supported by vhost for now)
216 	 */
217 	desc_ev->lun[2] = 0 >> 8;
218 	desc_ev->lun[3] = 0 & 0xFF;
219 	/* virtio doesn't specify any strict format for LUN id (bytes 2 and 3)
220 	 * current implementation relies on linux kernel sources
221 	 */
222 	memset(&desc_ev->lun[4], 0, 4);
223 	desc_ev->reason = reason;
224 	req_size = sizeof(*desc_ev);
225 
226 out:
227 	spdk_vhost_vq_used_ring_enqueue(vsession, vq, req, req_size);
228 }
229 
230 static void
231 submit_completion(struct spdk_vhost_scsi_task *task)
232 {
233 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
234 
235 	spdk_vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
236 					task->used_len);
237 	SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "Finished task (%p) req_idx=%d\n", task, task->req_idx);
238 
239 	spdk_vhost_scsi_task_put(task);
240 }
241 
242 static void
243 spdk_vhost_scsi_task_mgmt_cpl(struct spdk_scsi_task *scsi_task)
244 {
245 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
246 
247 	submit_completion(task);
248 }
249 
250 static void
251 spdk_vhost_scsi_task_cpl(struct spdk_scsi_task *scsi_task)
252 {
253 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
254 
255 	/* The SCSI task has completed.  Do final processing and then post
256 	   notification to the virtqueue's "used" ring.
257 	 */
258 	task->resp->status = task->scsi.status;
259 
260 	if (task->scsi.status != SPDK_SCSI_STATUS_GOOD) {
261 		memcpy(task->resp->sense, task->scsi.sense_data, task->scsi.sense_data_len);
262 		task->resp->sense_len = task->scsi.sense_data_len;
263 		SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "Task (%p) req_idx=%d failed - status=%u\n", task, task->req_idx,
264 			      task->scsi.status);
265 	}
266 	assert(task->scsi.transfer_len == task->scsi.length);
267 	task->resp->resid = task->scsi.length - task->scsi.data_transferred;
268 
269 	submit_completion(task);
270 }
271 
272 static void
273 task_submit(struct spdk_vhost_scsi_task *task)
274 {
275 	task->resp->response = VIRTIO_SCSI_S_OK;
276 	spdk_scsi_dev_queue_task(task->scsi_dev, &task->scsi);
277 }
278 
279 static void
280 mgmt_task_submit(struct spdk_vhost_scsi_task *task, enum spdk_scsi_task_func func)
281 {
282 	task->tmf_resp->response = VIRTIO_SCSI_S_OK;
283 	task->scsi.function = func;
284 	spdk_scsi_dev_queue_mgmt_task(task->scsi_dev, &task->scsi);
285 }
286 
287 static void
288 invalid_request(struct spdk_vhost_scsi_task *task)
289 {
290 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
291 
292 	spdk_vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
293 					task->used_len);
294 	spdk_vhost_scsi_task_put(task);
295 
296 	SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "Invalid request (status=%" PRIu8")\n",
297 		      task->resp ? task->resp->response : -1);
298 }
299 
300 static int
301 spdk_vhost_scsi_task_init_target(struct spdk_vhost_scsi_task *task, const __u8 *lun)
302 {
303 	struct spdk_vhost_scsi_dev *svdev = task->svsession->svdev;
304 	struct spdk_scsi_dev_vhost_state *state;
305 	uint16_t lun_id = (((uint16_t)lun[2] << 8) | lun[3]) & 0x3FFF;
306 
307 	SPDK_LOGDUMP(SPDK_LOG_VHOST_SCSI_QUEUE, "LUN", lun, 8);
308 
309 	/* First byte must be 1 and second is target */
310 	if (lun[0] != 1 || lun[1] >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
311 		return -1;
312 	}
313 
314 	state = &svdev->scsi_dev_state[lun[1]];
315 	task->scsi_dev = state->dev;
316 	if (state->dev == NULL || svdev->scsi_dev_state[lun[1]].removed) {
317 		/* If dev has been hotdetached, return 0 to allow sending
318 		 * additional hotremove event via sense codes.
319 		 */
320 		return svdev->scsi_dev_state[lun[1]].removed ? 0 : -1;
321 	}
322 
323 	task->scsi.target_port = spdk_scsi_dev_find_port_by_id(task->scsi_dev, 0);
324 	task->scsi.lun = spdk_scsi_dev_get_lun(state->dev, lun_id);
325 	return 0;
326 }
327 
328 static void
329 process_ctrl_request(struct spdk_vhost_scsi_task *task)
330 {
331 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
332 	struct spdk_vhost_dev *vdev = vsession->vdev;
333 	struct vring_desc *desc, *desc_table;
334 	struct virtio_scsi_ctrl_tmf_req *ctrl_req;
335 	struct virtio_scsi_ctrl_an_resp *an_resp;
336 	uint32_t desc_table_size, used_len = 0;
337 	int rc;
338 
339 	spdk_scsi_task_construct(&task->scsi, spdk_vhost_scsi_task_mgmt_cpl, spdk_vhost_scsi_task_free_cb);
340 	rc = spdk_vhost_vq_get_desc(vsession, task->vq, task->req_idx, &desc, &desc_table,
341 				    &desc_table_size);
342 	if (spdk_unlikely(rc != 0)) {
343 		SPDK_ERRLOG("%s: Invalid controlq descriptor at index %d.\n",
344 			    vdev->name, task->req_idx);
345 		goto out;
346 	}
347 
348 	ctrl_req = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(*ctrl_req));
349 	if (ctrl_req == NULL) {
350 		SPDK_ERRLOG("%s: Invalid task management request at index %d.\n",
351 			    vdev->name, task->req_idx);
352 		goto out;
353 	}
354 
355 	SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE,
356 		      "Processing controlq descriptor: desc %d/%p, desc_addr %p, len %d, flags %d, last_used_idx %d; kickfd %d; size %d\n",
357 		      task->req_idx, desc, (void *)desc->addr, desc->len, desc->flags, task->vq->vring.last_used_idx,
358 		      task->vq->vring.kickfd, task->vq->vring.size);
359 	SPDK_LOGDUMP(SPDK_LOG_VHOST_SCSI_QUEUE, "Request descriptor", (uint8_t *)ctrl_req, desc->len);
360 
361 	spdk_vhost_scsi_task_init_target(task, ctrl_req->lun);
362 
363 	spdk_vhost_vring_desc_get_next(&desc, desc_table, desc_table_size);
364 	if (spdk_unlikely(desc == NULL)) {
365 		SPDK_ERRLOG("%s: No response descriptor for controlq request %d.\n",
366 			    vdev->name, task->req_idx);
367 		goto out;
368 	}
369 
370 	/* Process the TMF request */
371 	switch (ctrl_req->type) {
372 	case VIRTIO_SCSI_T_TMF:
373 		task->tmf_resp = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->tmf_resp));
374 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_tmf_resp) || task->tmf_resp == NULL)) {
375 			SPDK_ERRLOG("%s: TMF response descriptor at index %d points to invalid guest memory region\n",
376 				    vdev->name, task->req_idx);
377 			goto out;
378 		}
379 
380 		/* Check if we are processing a valid request */
381 		if (task->scsi_dev == NULL) {
382 			task->tmf_resp->response = VIRTIO_SCSI_S_BAD_TARGET;
383 			break;
384 		}
385 
386 		switch (ctrl_req->subtype) {
387 		case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
388 			/* Handle LUN reset */
389 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE, "LUN reset\n");
390 
391 			mgmt_task_submit(task, SPDK_SCSI_TASK_FUNC_LUN_RESET);
392 			return;
393 		default:
394 			task->tmf_resp->response = VIRTIO_SCSI_S_ABORTED;
395 			/* Unsupported command */
396 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE, "Unsupported TMF command %x\n", ctrl_req->subtype);
397 			break;
398 		}
399 		break;
400 	case VIRTIO_SCSI_T_AN_QUERY:
401 	case VIRTIO_SCSI_T_AN_SUBSCRIBE: {
402 		an_resp = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(*an_resp));
403 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_an_resp) || an_resp == NULL)) {
404 			SPDK_WARNLOG("%s: Asynchronous response descriptor points to invalid guest memory region\n",
405 				     vdev->name);
406 			goto out;
407 		}
408 
409 		an_resp->response = VIRTIO_SCSI_S_ABORTED;
410 		break;
411 	}
412 	default:
413 		SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE, "Unsupported control command %x\n", ctrl_req->type);
414 		break;
415 	}
416 
417 	used_len = sizeof(struct virtio_scsi_ctrl_tmf_resp);
418 out:
419 	spdk_vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx, used_len);
420 	spdk_vhost_scsi_task_put(task);
421 }
422 
423 /*
424  * Process task's descriptor chain and setup data related fields.
425  * Return
426  *   -1 if request is invalid and must be aborted,
427  *    0 if all data are set.
428  */
429 static int
430 task_data_setup(struct spdk_vhost_scsi_task *task,
431 		struct virtio_scsi_cmd_req **req)
432 {
433 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
434 	struct spdk_vhost_dev *vdev = vsession->vdev;
435 	struct vring_desc *desc, *desc_table;
436 	struct iovec *iovs = task->iovs;
437 	uint16_t iovcnt = 0;
438 	uint32_t desc_table_len, len = 0;
439 	int rc;
440 
441 	spdk_scsi_task_construct(&task->scsi, spdk_vhost_scsi_task_cpl, spdk_vhost_scsi_task_free_cb);
442 
443 	rc = spdk_vhost_vq_get_desc(vsession, task->vq, task->req_idx, &desc, &desc_table, &desc_table_len);
444 	/* First descriptor must be readable */
445 	if (spdk_unlikely(rc != 0  || spdk_vhost_vring_desc_is_wr(desc) ||
446 			  desc->len < sizeof(struct virtio_scsi_cmd_req))) {
447 		SPDK_WARNLOG("%s: invalid first (request) descriptor at index %"PRIu16".\n",
448 			     vdev->name, task->req_idx);
449 		goto invalid_task;
450 	}
451 
452 	*req = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(**req));
453 	if (spdk_unlikely(*req == NULL)) {
454 		SPDK_WARNLOG("%s: Request descriptor at index %d points to invalid guest memory region\n",
455 			     vdev->name, task->req_idx);
456 		goto invalid_task;
457 	}
458 
459 	/* Each request must have at least 2 descriptors (e.g. request and response) */
460 	spdk_vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
461 	if (desc == NULL) {
462 		SPDK_WARNLOG("%s: Descriptor chain at index %d contains neither payload nor response buffer.\n",
463 			     vdev->name, task->req_idx);
464 		goto invalid_task;
465 	}
466 	task->scsi.dxfer_dir = spdk_vhost_vring_desc_is_wr(desc) ? SPDK_SCSI_DIR_FROM_DEV :
467 			       SPDK_SCSI_DIR_TO_DEV;
468 	task->scsi.iovs = iovs;
469 
470 	if (task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV) {
471 		/*
472 		 * FROM_DEV (READ): [RD_req][WR_resp][WR_buf0]...[WR_bufN]
473 		 */
474 		task->resp = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->resp));
475 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) {
476 			SPDK_WARNLOG("%s: Response descriptor at index %d points to invalid guest memory region\n",
477 				     vdev->name, task->req_idx);
478 			goto invalid_task;
479 		}
480 		rc = spdk_vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
481 		if (spdk_unlikely(rc != 0)) {
482 			SPDK_WARNLOG("%s: invalid descriptor chain at request index %d (descriptor id overflow?).\n",
483 				     vdev->name, task->req_idx);
484 			goto invalid_task;
485 		}
486 
487 		if (desc == NULL) {
488 			/*
489 			 * TEST UNIT READY command and some others might not contain any payload and this is not an error.
490 			 */
491 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_DATA,
492 				      "No payload descriptors for FROM DEV command req_idx=%"PRIu16".\n", task->req_idx);
493 			SPDK_LOGDUMP(SPDK_LOG_VHOST_SCSI_DATA, "CDB=", (*req)->cdb, VIRTIO_SCSI_CDB_SIZE);
494 			task->used_len = sizeof(struct virtio_scsi_cmd_resp);
495 			task->scsi.iovcnt = 1;
496 			task->scsi.iovs[0].iov_len = 0;
497 			task->scsi.length = 0;
498 			task->scsi.transfer_len = 0;
499 			return 0;
500 		}
501 
502 		/* All remaining descriptors are data. */
503 		while (desc) {
504 			if (spdk_unlikely(!spdk_vhost_vring_desc_is_wr(desc))) {
505 				SPDK_WARNLOG("FROM DEV cmd: descriptor nr %" PRIu16" in payload chain is read only.\n", iovcnt);
506 				goto invalid_task;
507 			}
508 
509 			if (spdk_unlikely(spdk_vhost_vring_desc_to_iov(vsession, iovs, &iovcnt, desc))) {
510 				goto invalid_task;
511 			}
512 			len += desc->len;
513 
514 			rc = spdk_vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
515 			if (spdk_unlikely(rc != 0)) {
516 				SPDK_WARNLOG("%s: invalid payload in descriptor chain starting at index %d.\n",
517 					     vdev->name, task->req_idx);
518 				goto invalid_task;
519 			}
520 		}
521 
522 		task->used_len = sizeof(struct virtio_scsi_cmd_resp) + len;
523 	} else {
524 		SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_DATA, "TO DEV");
525 		/*
526 		 * TO_DEV (WRITE):[RD_req][RD_buf0]...[RD_bufN][WR_resp]
527 		 * No need to check descriptor WR flag as this is done while setting scsi.dxfer_dir.
528 		 */
529 
530 		/* Process descriptors up to response. */
531 		while (!spdk_vhost_vring_desc_is_wr(desc)) {
532 			if (spdk_unlikely(spdk_vhost_vring_desc_to_iov(vsession, iovs, &iovcnt, desc))) {
533 				goto invalid_task;
534 			}
535 			len += desc->len;
536 
537 			spdk_vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
538 			if (spdk_unlikely(desc == NULL)) {
539 				SPDK_WARNLOG("TO_DEV cmd: no response descriptor.\n");
540 				goto invalid_task;
541 			}
542 		}
543 
544 		task->resp = spdk_vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->resp));
545 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) {
546 			SPDK_WARNLOG("%s: Response descriptor at index %d points to invalid guest memory region\n",
547 				     vdev->name, task->req_idx);
548 			goto invalid_task;
549 		}
550 
551 		task->used_len = sizeof(struct virtio_scsi_cmd_resp);
552 	}
553 
554 	task->scsi.iovcnt = iovcnt;
555 	task->scsi.length = len;
556 	task->scsi.transfer_len = len;
557 	return 0;
558 
559 invalid_task:
560 	SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_DATA, "%s: Invalid task at index %"PRIu16".\n",
561 		      vdev->name, task->req_idx);
562 	return -1;
563 }
564 
565 static int
566 process_request(struct spdk_vhost_scsi_task *task)
567 {
568 	struct virtio_scsi_cmd_req *req;
569 	int result;
570 
571 	result = task_data_setup(task, &req);
572 	if (result) {
573 		return result;
574 	}
575 
576 	result = spdk_vhost_scsi_task_init_target(task, req->lun);
577 	if (spdk_unlikely(result != 0)) {
578 		task->resp->response = VIRTIO_SCSI_S_BAD_TARGET;
579 		return -1;
580 	}
581 
582 	task->scsi.cdb = req->cdb;
583 	SPDK_LOGDUMP(SPDK_LOG_VHOST_SCSI_DATA, "request CDB", req->cdb, VIRTIO_SCSI_CDB_SIZE);
584 
585 	if (spdk_unlikely(task->scsi.lun == NULL)) {
586 		spdk_scsi_task_process_null_lun(&task->scsi);
587 		task->resp->response = VIRTIO_SCSI_S_OK;
588 		return 1;
589 	}
590 
591 	return 0;
592 }
593 
594 static void
595 process_controlq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_virtqueue *vq)
596 {
597 	struct spdk_vhost_scsi_dev *svdev = svsession->svdev;
598 	struct spdk_vhost_session *vsession = svdev->vdev.session;
599 	struct spdk_vhost_scsi_task *task;
600 	uint16_t reqs[32];
601 	uint16_t reqs_cnt, i;
602 
603 	reqs_cnt = spdk_vhost_vq_avail_ring_get(vq, reqs, SPDK_COUNTOF(reqs));
604 	for (i = 0; i < reqs_cnt; i++) {
605 		if (spdk_unlikely(reqs[i] >= vq->vring.size)) {
606 			SPDK_ERRLOG("%s: invalid entry in avail ring. Buffer '%"PRIu16"' exceeds virtqueue size (%"PRIu16")\n",
607 				    svdev->vdev.name, reqs[i], vq->vring.size);
608 			spdk_vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
609 			continue;
610 		}
611 
612 		task = &((struct spdk_vhost_scsi_task *)vq->tasks)[reqs[i]];
613 		if (spdk_unlikely(task->used)) {
614 			SPDK_ERRLOG("%s: invalid entry in avail ring. Buffer '%"PRIu16"' is still in use!\n",
615 				    svdev->vdev.name, reqs[i]);
616 			spdk_vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
617 			continue;
618 		}
619 
620 		vsession->task_cnt++;
621 		memset(&task->scsi, 0, sizeof(task->scsi));
622 		task->tmf_resp = NULL;
623 		task->used = true;
624 		process_ctrl_request(task);
625 	}
626 }
627 
628 static void
629 process_requestq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_virtqueue *vq)
630 {
631 	struct spdk_vhost_session *vsession = &svsession->vsession;
632 	struct spdk_vhost_dev *vdev = vsession->vdev;
633 	struct spdk_vhost_scsi_task *task;
634 	uint16_t reqs[32];
635 	uint16_t reqs_cnt, i;
636 	int result;
637 
638 	reqs_cnt = spdk_vhost_vq_avail_ring_get(vq, reqs, SPDK_COUNTOF(reqs));
639 	assert(reqs_cnt <= 32);
640 
641 	for (i = 0; i < reqs_cnt; i++) {
642 		SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Starting processing request idx %"PRIu16"======\n",
643 			      reqs[i]);
644 
645 		if (spdk_unlikely(reqs[i] >= vq->vring.size)) {
646 			SPDK_ERRLOG("%s: request idx '%"PRIu16"' exceeds virtqueue size (%"PRIu16").\n",
647 				    vdev->name, reqs[i], vq->vring.size);
648 			spdk_vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
649 			continue;
650 		}
651 
652 		task = &((struct spdk_vhost_scsi_task *)vq->tasks)[reqs[i]];
653 		if (spdk_unlikely(task->used)) {
654 			SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
655 				    vdev->name, reqs[i]);
656 			spdk_vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
657 			continue;
658 		}
659 
660 		vsession->task_cnt++;
661 		memset(&task->scsi, 0, sizeof(task->scsi));
662 		task->resp = NULL;
663 		task->used = true;
664 		task->used_len = 0;
665 		result = process_request(task);
666 		if (likely(result == 0)) {
667 			task_submit(task);
668 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d submitted ======\n", task,
669 				      task->req_idx);
670 		} else if (result > 0) {
671 			spdk_vhost_scsi_task_cpl(&task->scsi);
672 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d finished early ======\n", task,
673 				      task->req_idx);
674 		} else {
675 			invalid_request(task);
676 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d failed ======\n", task,
677 				      task->req_idx);
678 		}
679 	}
680 }
681 
682 static int
683 vdev_mgmt_worker(void *arg)
684 {
685 	struct spdk_vhost_scsi_session *svsession = arg;
686 	struct spdk_vhost_scsi_dev *svdev = svsession->svdev;
687 	struct spdk_vhost_session *vsession = &svsession->vsession;
688 
689 	process_removed_devs(svdev);
690 	spdk_vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]);
691 
692 	process_controlq(svsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);
693 	spdk_vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);
694 
695 	return -1;
696 }
697 
698 static int
699 vdev_worker(void *arg)
700 {
701 	struct spdk_vhost_scsi_session *svsession = arg;
702 	struct spdk_vhost_session *vsession = &svsession->vsession;
703 	uint32_t q_idx;
704 
705 	for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vsession->max_queues; q_idx++) {
706 		process_requestq(svsession, &vsession->virtqueue[q_idx]);
707 	}
708 
709 	spdk_vhost_session_used_signal(vsession);
710 
711 	return -1;
712 }
713 
714 static struct spdk_vhost_scsi_dev *
715 to_scsi_dev(struct spdk_vhost_dev *ctrlr)
716 {
717 	if (ctrlr == NULL) {
718 		return NULL;
719 	}
720 
721 	if (ctrlr->backend != &spdk_vhost_scsi_device_backend) {
722 		SPDK_ERRLOG("%s: not a vhost-scsi device.\n", ctrlr->name);
723 		return NULL;
724 	}
725 
726 	return SPDK_CONTAINEROF(ctrlr, struct spdk_vhost_scsi_dev, vdev);
727 }
728 
729 static struct spdk_vhost_scsi_session *
730 to_scsi_session(struct spdk_vhost_session *vsession)
731 {
732 	if (vsession == NULL) {
733 		return NULL;
734 	}
735 
736 	if (vsession->vdev->backend != &spdk_vhost_scsi_device_backend) {
737 		SPDK_ERRLOG("%s: not a vhost-scsi device.\n", vsession->vdev->name);
738 		return NULL;
739 	}
740 
741 	return (struct spdk_vhost_scsi_session *)vsession;
742 }
743 
744 int
745 spdk_vhost_scsi_dev_construct(const char *name, const char *cpumask)
746 {
747 	struct spdk_vhost_scsi_dev *svdev = spdk_dma_zmalloc(sizeof(struct spdk_vhost_scsi_dev),
748 					    SPDK_CACHE_LINE_SIZE, NULL);
749 	int rc;
750 
751 	if (svdev == NULL) {
752 		return -ENOMEM;
753 	}
754 
755 	spdk_vhost_lock();
756 	rc = spdk_vhost_dev_register(&svdev->vdev, name, cpumask,
757 				     &spdk_vhost_scsi_device_backend);
758 
759 	if (rc) {
760 		spdk_dma_free(svdev);
761 	}
762 
763 	spdk_vhost_unlock();
764 	return rc;
765 }
766 
767 static int
768 spdk_vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev)
769 {
770 	struct spdk_vhost_scsi_dev *svdev = to_scsi_dev(vdev);
771 	int rc, i;
772 
773 	if (svdev == NULL) {
774 		return -EINVAL;
775 	}
776 
777 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) {
778 		if (svdev->scsi_dev_state[i].dev) {
779 			if (vdev->registered) {
780 				SPDK_ERRLOG("Trying to remove non-empty controller: %s.\n", vdev->name);
781 				return -EBUSY;
782 			}
783 
784 			rc = spdk_vhost_scsi_dev_remove_tgt(vdev, i, NULL, NULL);
785 			if (rc != 0) {
786 				SPDK_ERRLOG("%s: failed to force-remove target %d\n", vdev->name, i);
787 				return rc;
788 			}
789 		}
790 	}
791 
792 	rc = spdk_vhost_dev_unregister(vdev);
793 	if (rc != 0) {
794 		return rc;
795 	}
796 
797 	spdk_dma_free(svdev);
798 	return 0;
799 }
800 
801 struct spdk_scsi_dev *
802 spdk_vhost_scsi_dev_get_tgt(struct spdk_vhost_dev *vdev, uint8_t num)
803 {
804 	struct spdk_vhost_scsi_dev *svdev;
805 
806 	assert(num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
807 	svdev = to_scsi_dev(vdev);
808 
809 	return svdev ? svdev->scsi_dev_state[num].dev : NULL;
810 }
811 
812 static void
813 spdk_vhost_scsi_lun_hotremove(const struct spdk_scsi_lun *lun, void *arg)
814 {
815 	struct spdk_vhost_scsi_dev *svdev = arg;
816 	const struct spdk_scsi_dev *scsi_dev;
817 	unsigned scsi_dev_num;
818 
819 	assert(lun != NULL);
820 	assert(svdev != NULL);
821 	scsi_dev = spdk_scsi_lun_get_dev(lun);
822 	for (scsi_dev_num = 0; scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_dev_num++) {
823 		if (svdev->scsi_dev_state[scsi_dev_num].dev == scsi_dev) {
824 			break;
825 		}
826 	}
827 
828 	if (scsi_dev_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
829 		/* The entire device has been already removed. */
830 		return;
831 	}
832 
833 	/* remove entire device */
834 	spdk_vhost_scsi_dev_remove_tgt(&svdev->vdev, scsi_dev_num, NULL, NULL);
835 }
836 
837 int
838 spdk_vhost_scsi_dev_add_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num,
839 			    const char *bdev_name)
840 {
841 	struct spdk_vhost_scsi_dev *svdev;
842 	struct spdk_scsi_dev_vhost_state *state;
843 	char target_name[SPDK_SCSI_DEV_MAX_NAME];
844 	int lun_id_list[1];
845 	const char *bdev_names_list[1];
846 
847 	svdev = to_scsi_dev(vdev);
848 	if (svdev == NULL) {
849 		return -EINVAL;
850 	}
851 
852 	if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
853 		SPDK_ERRLOG("Controller %d target number too big (max %d)\n", scsi_tgt_num,
854 			    SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
855 		return -EINVAL;
856 	}
857 
858 	if (bdev_name == NULL) {
859 		SPDK_ERRLOG("No lun name specified\n");
860 		return -EINVAL;
861 	}
862 
863 	state = &svdev->scsi_dev_state[scsi_tgt_num];
864 	if (state->dev != NULL) {
865 		SPDK_ERRLOG("Controller %s target %u already occupied\n", vdev->name, scsi_tgt_num);
866 		return -EEXIST;
867 	}
868 
869 	/*
870 	 * At this stage only one LUN per target
871 	 */
872 	snprintf(target_name, sizeof(target_name), "Target %u", scsi_tgt_num);
873 	lun_id_list[0] = 0;
874 	bdev_names_list[0] = (char *)bdev_name;
875 
876 	state->removed = false;
877 	state->dev = spdk_scsi_dev_construct(target_name, bdev_names_list, lun_id_list, 1,
878 					     SPDK_SPC_PROTOCOL_IDENTIFIER_SAS,
879 					     spdk_vhost_scsi_lun_hotremove, svdev);
880 
881 	if (state->dev == NULL) {
882 		SPDK_ERRLOG("Couldn't create spdk SCSI target '%s' using bdev '%s' in controller: %s\n",
883 			    target_name, bdev_name, vdev->name);
884 		return -EINVAL;
885 	}
886 	spdk_scsi_dev_add_port(state->dev, 0, "vhost");
887 
888 	SPDK_INFOLOG(SPDK_LOG_VHOST, "Controller %s: defined target '%s' using bdev '%s'\n",
889 		     vdev->name, target_name, bdev_name);
890 
891 	if (vdev->lcore == -1) {
892 		/* All done. */
893 		return 0;
894 	}
895 
896 	spdk_scsi_dev_allocate_io_channels(state->dev);
897 
898 	if (spdk_vhost_dev_has_feature(vdev->session, VIRTIO_SCSI_F_HOTPLUG)) {
899 		eventq_enqueue((struct spdk_vhost_scsi_session *)vdev->session, scsi_tgt_num,
900 			       VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_RESCAN);
901 	} else {
902 		SPDK_NOTICELOG("Device %s does not support hotplug. "
903 			       "Please restart the driver or perform a rescan.\n",
904 			       vdev->name);
905 	}
906 
907 	return 0;
908 }
909 
910 int
911 spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num,
912 			       spdk_vhost_event_fn cb_fn, void *cb_arg)
913 {
914 	struct spdk_vhost_scsi_dev *svdev;
915 	struct spdk_scsi_dev_vhost_state *scsi_dev_state;
916 	int rc = 0;
917 
918 	if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
919 		SPDK_ERRLOG("%s: invalid target number %d\n", vdev->name, scsi_tgt_num);
920 		return -EINVAL;
921 	}
922 
923 	svdev = to_scsi_dev(vdev);
924 	if (svdev == NULL) {
925 		return -ENODEV;
926 	}
927 
928 	scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num];
929 	if (scsi_dev_state->dev == NULL) {
930 		SPDK_ERRLOG("Controller %s target %u is not occupied\n", vdev->name, scsi_tgt_num);
931 		return -ENODEV;
932 	}
933 
934 	if (svdev->vdev.lcore == -1) {
935 		/* controller is not in use, remove dev and exit */
936 		svdev->scsi_dev_state[scsi_tgt_num].dev = NULL;
937 		spdk_scsi_dev_destruct(scsi_dev_state->dev);
938 		if (cb_fn) {
939 			rc = cb_fn(vdev, cb_arg);
940 		}
941 		SPDK_INFOLOG(SPDK_LOG_VHOST, "%s: removed target 'Target %u'\n",
942 			     vdev->name, scsi_tgt_num);
943 		return rc;
944 	}
945 
946 	if (scsi_dev_state->removed) {
947 		SPDK_WARNLOG("%s: 'Target %u' has been already marked to hotremove.\n", svdev->vdev.name,
948 			     scsi_tgt_num);
949 		return -EBUSY;
950 	}
951 
952 	scsi_dev_state->remove_cb = cb_fn;
953 	scsi_dev_state->remove_ctx = cb_arg;
954 	scsi_dev_state->removed = true;
955 
956 	if (spdk_vhost_dev_has_feature(vdev->session, VIRTIO_SCSI_F_HOTPLUG)) {
957 		eventq_enqueue((struct spdk_vhost_scsi_session *)vdev->session, scsi_tgt_num,
958 			       VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_REMOVED);
959 	}
960 
961 	SPDK_INFOLOG(SPDK_LOG_VHOST, "%s: queued 'Target %u' for hot-detach.\n", vdev->name, scsi_tgt_num);
962 	return 0;
963 }
964 
965 int
966 spdk_vhost_scsi_controller_construct(void)
967 {
968 	struct spdk_conf_section *sp = spdk_conf_first_section(NULL);
969 	struct spdk_vhost_dev *vdev;
970 	int i, dev_num;
971 	unsigned ctrlr_num = 0;
972 	char *bdev_name, *tgt_num_str;
973 	char *cpumask;
974 	char *name;
975 	char *tgt = NULL;
976 
977 	while (sp != NULL) {
978 		if (!spdk_conf_section_match_prefix(sp, "VhostScsi")) {
979 			sp = spdk_conf_next_section(sp);
980 			continue;
981 		}
982 
983 		if (sscanf(spdk_conf_section_get_name(sp), "VhostScsi%u", &ctrlr_num) != 1) {
984 			SPDK_ERRLOG("Section '%s' has non-numeric suffix.\n",
985 				    spdk_conf_section_get_name(sp));
986 			return -1;
987 		}
988 
989 		name =  spdk_conf_section_get_val(sp, "Name");
990 		cpumask = spdk_conf_section_get_val(sp, "Cpumask");
991 
992 		if (spdk_vhost_scsi_dev_construct(name, cpumask) < 0) {
993 			return -1;
994 		}
995 
996 		vdev = spdk_vhost_dev_find(name);
997 		assert(vdev);
998 
999 		for (i = 0; ; i++) {
1000 
1001 			tgt = spdk_conf_section_get_nval(sp, "Target", i);
1002 			if (tgt == NULL) {
1003 				break;
1004 			}
1005 
1006 			tgt_num_str = spdk_conf_section_get_nmval(sp, "Target", i, 0);
1007 			if (tgt_num_str == NULL) {
1008 				SPDK_ERRLOG("%s: Invalid or missing target number\n", name);
1009 				return -1;
1010 			}
1011 
1012 			dev_num = (int)strtol(tgt_num_str, NULL, 10);
1013 			bdev_name = spdk_conf_section_get_nmval(sp, "Target", i, 1);
1014 			if (bdev_name == NULL) {
1015 				SPDK_ERRLOG("%s: Invalid or missing bdev name for target %d\n", name, dev_num);
1016 				return -1;
1017 			} else if (spdk_conf_section_get_nmval(sp, "Target", i, 2)) {
1018 				SPDK_ERRLOG("%s: Only one LUN per vhost SCSI device supported\n", name);
1019 				return -1;
1020 			}
1021 
1022 			if (spdk_vhost_scsi_dev_add_tgt(vdev, dev_num, bdev_name) < 0) {
1023 				return -1;
1024 			}
1025 		}
1026 
1027 		sp = spdk_conf_next_section(sp);
1028 	}
1029 
1030 	return 0;
1031 }
1032 
1033 static void
1034 free_task_pool(struct spdk_vhost_scsi_session *svsession)
1035 {
1036 	struct spdk_vhost_session *vsession = &svsession->vsession;
1037 	struct spdk_vhost_virtqueue *vq;
1038 	uint16_t i;
1039 
1040 	for (i = 0; i < vsession->max_queues; i++) {
1041 		vq = &vsession->virtqueue[i];
1042 		if (vq->tasks == NULL) {
1043 			continue;
1044 		}
1045 
1046 		spdk_dma_free(vq->tasks);
1047 		vq->tasks = NULL;
1048 	}
1049 }
1050 
1051 static int
1052 alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
1053 {
1054 	struct spdk_vhost_session *vsession = &svsession->vsession;
1055 	struct spdk_vhost_scsi_dev *svdev = svsession->svdev;
1056 	struct spdk_vhost_virtqueue *vq;
1057 	struct spdk_vhost_scsi_task *task;
1058 	uint32_t task_cnt;
1059 	uint16_t i;
1060 	uint32_t j;
1061 
1062 	for (i = 0; i < vsession->max_queues; i++) {
1063 		vq = &vsession->virtqueue[i];
1064 		if (vq->vring.desc == NULL) {
1065 			continue;
1066 		}
1067 
1068 		task_cnt = vq->vring.size;
1069 		if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
1070 			/* sanity check */
1071 			SPDK_ERRLOG("Controller %s: virtuque %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
1072 				    svdev->vdev.name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
1073 			free_task_pool(svsession);
1074 			return -1;
1075 		}
1076 		vq->tasks = spdk_dma_zmalloc(sizeof(struct spdk_vhost_scsi_task) * task_cnt,
1077 					     SPDK_CACHE_LINE_SIZE, NULL);
1078 		if (vq->tasks == NULL) {
1079 			SPDK_ERRLOG("Controller %s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
1080 				    svdev->vdev.name, task_cnt, i);
1081 			free_task_pool(svsession);
1082 			return -1;
1083 		}
1084 
1085 		for (j = 0; j < task_cnt; j++) {
1086 			task = &((struct spdk_vhost_scsi_task *)vq->tasks)[j];
1087 			task->svsession = svsession;
1088 			task->vq = vq;
1089 			task->req_idx = j;
1090 		}
1091 	}
1092 
1093 	return 0;
1094 }
1095 
1096 /*
1097  * A new device is added to a data core. First the device is added to the main linked list
1098  * and then allocated to a specific data core.
1099  */
1100 static int
1101 spdk_vhost_scsi_start(struct spdk_vhost_dev *vdev, void *event_ctx)
1102 {
1103 	struct spdk_vhost_scsi_dev *svdev;
1104 	struct spdk_vhost_session *vsession = vdev->session;
1105 	struct spdk_vhost_scsi_session *svsession;
1106 	uint32_t i;
1107 	int rc;
1108 
1109 	svsession = to_scsi_session(vsession);
1110 	if (svsession == NULL) {
1111 		SPDK_ERRLOG("Trying to start non-scsi controller as a scsi one.\n");
1112 		rc = -1;
1113 		goto out;
1114 	}
1115 
1116 	svdev = to_scsi_dev(vdev);
1117 	svsession->svdev = svdev;
1118 
1119 	/* validate all I/O queues are in a contiguous index range */
1120 	for (i = VIRTIO_SCSI_REQUESTQ; i < vsession->max_queues; i++) {
1121 		if (vsession->virtqueue[i].vring.desc == NULL) {
1122 			SPDK_ERRLOG("%s: queue %"PRIu32" is empty\n", vsession->vdev->name, i);
1123 			rc = -1;
1124 			goto out;
1125 		}
1126 	}
1127 
1128 	rc = alloc_task_pool(svsession);
1129 	if (rc != 0) {
1130 		SPDK_ERRLOG("%s: failed to alloc task pool.\n", vdev->name);
1131 		goto out;
1132 	}
1133 
1134 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1135 		if (svdev->scsi_dev_state[i].dev == NULL) {
1136 			continue;
1137 		}
1138 		spdk_scsi_dev_allocate_io_channels(svdev->scsi_dev_state[i].dev);
1139 	}
1140 	SPDK_INFOLOG(SPDK_LOG_VHOST, "Started poller for vhost controller %s on lcore %d\n",
1141 		     vdev->name, vdev->lcore);
1142 
1143 	svsession->requestq_poller = spdk_poller_register(vdev_worker, svsession, 0);
1144 	if (vsession->virtqueue[VIRTIO_SCSI_CONTROLQ].vring.desc &&
1145 	    vsession->virtqueue[VIRTIO_SCSI_EVENTQ].vring.desc) {
1146 		svsession->mgmt_poller = spdk_poller_register(vdev_mgmt_worker, svsession,
1147 					 MGMT_POLL_PERIOD_US);
1148 	}
1149 out:
1150 	spdk_vhost_dev_backend_event_done(event_ctx, rc);
1151 	return rc;
1152 }
1153 
1154 static int
1155 destroy_session_poller_cb(void *arg)
1156 {
1157 	struct spdk_vhost_scsi_session *svsession = arg;
1158 	struct spdk_vhost_scsi_dev *svdev = svsession->svdev;
1159 	struct spdk_vhost_session *vsession = &svsession->vsession;
1160 	uint32_t i;
1161 
1162 	if (vsession->task_cnt > 0) {
1163 		return -1;
1164 	}
1165 
1166 
1167 	for (i = 0; i < vsession->max_queues; i++) {
1168 		spdk_vhost_vq_used_signal(vsession, &vsession->virtqueue[i]);
1169 	}
1170 
1171 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1172 		if (svdev->scsi_dev_state[i].dev == NULL) {
1173 			continue;
1174 		}
1175 
1176 		spdk_scsi_dev_free_io_channels(svdev->scsi_dev_state[i].dev);
1177 	}
1178 
1179 	SPDK_INFOLOG(SPDK_LOG_VHOST, "Stopping poller for vhost controller %s\n", svdev->vdev.name);
1180 
1181 	free_task_pool(svsession);
1182 
1183 	spdk_poller_unregister(&svsession->destroy_ctx.poller);
1184 	spdk_vhost_dev_backend_event_done(svsession->destroy_ctx.event_ctx, 0);
1185 
1186 	return -1;
1187 }
1188 
1189 static int
1190 spdk_vhost_scsi_stop(struct spdk_vhost_dev *vdev, void *event_ctx)
1191 {
1192 	struct spdk_vhost_session *vsession = vdev->session;
1193 	struct spdk_vhost_scsi_session *svsession;
1194 
1195 	svsession = to_scsi_session(vsession);
1196 	if (svsession == NULL) {
1197 		SPDK_ERRLOG("Trying to stop non-scsi controller as a scsi one.\n");
1198 		goto err;
1199 	}
1200 
1201 	svsession->destroy_ctx.event_ctx = event_ctx;
1202 	spdk_poller_unregister(&svsession->requestq_poller);
1203 	spdk_poller_unregister(&svsession->mgmt_poller);
1204 	svsession->destroy_ctx.poller = spdk_poller_register(destroy_session_poller_cb,
1205 					svsession, 1000);
1206 
1207 	return 0;
1208 
1209 err:
1210 	spdk_vhost_dev_backend_event_done(event_ctx, -1);
1211 	return -1;
1212 }
1213 
1214 static void
1215 spdk_vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
1216 {
1217 	struct spdk_scsi_dev *sdev;
1218 	struct spdk_scsi_lun *lun;
1219 	uint32_t dev_idx;
1220 	uint32_t lun_idx;
1221 
1222 	assert(vdev != NULL);
1223 	spdk_json_write_name(w, "scsi");
1224 	spdk_json_write_array_begin(w);
1225 	for (dev_idx = 0; dev_idx < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; dev_idx++) {
1226 		sdev = spdk_vhost_scsi_dev_get_tgt(vdev, dev_idx);
1227 		if (!sdev) {
1228 			continue;
1229 		}
1230 
1231 		spdk_json_write_object_begin(w);
1232 
1233 		spdk_json_write_name(w, "scsi_dev_num");
1234 		spdk_json_write_uint32(w, dev_idx);
1235 
1236 		spdk_json_write_name(w, "id");
1237 		spdk_json_write_int32(w, spdk_scsi_dev_get_id(sdev));
1238 
1239 		spdk_json_write_name(w, "target_name");
1240 		spdk_json_write_string(w, spdk_scsi_dev_get_name(sdev));
1241 
1242 		spdk_json_write_name(w, "luns");
1243 		spdk_json_write_array_begin(w);
1244 
1245 		for (lun_idx = 0; lun_idx < SPDK_SCSI_DEV_MAX_LUN; lun_idx++) {
1246 			lun = spdk_scsi_dev_get_lun(sdev, lun_idx);
1247 			if (!lun) {
1248 				continue;
1249 			}
1250 
1251 			spdk_json_write_object_begin(w);
1252 
1253 			spdk_json_write_name(w, "id");
1254 			spdk_json_write_int32(w, spdk_scsi_lun_get_id(lun));
1255 
1256 			spdk_json_write_name(w, "bdev_name");
1257 			spdk_json_write_string(w, spdk_scsi_lun_get_bdev_name(lun));
1258 
1259 			spdk_json_write_object_end(w);
1260 		}
1261 
1262 		spdk_json_write_array_end(w);
1263 		spdk_json_write_object_end(w);
1264 	}
1265 
1266 	spdk_json_write_array_end(w);
1267 }
1268 
1269 static void
1270 spdk_vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
1271 {
1272 	struct spdk_vhost_scsi_dev *svdev;
1273 	struct spdk_scsi_lun *lun;
1274 	uint32_t i;
1275 
1276 	svdev = to_scsi_dev(vdev);
1277 	if (!svdev) {
1278 		return;
1279 	}
1280 
1281 	spdk_json_write_object_begin(w);
1282 	spdk_json_write_named_string(w, "method", "construct_vhost_scsi_controller");
1283 
1284 	spdk_json_write_named_object_begin(w, "params");
1285 	spdk_json_write_named_string(w, "ctrlr", vdev->name);
1286 	spdk_json_write_named_string(w, "cpumask", spdk_cpuset_fmt(vdev->cpumask));
1287 	spdk_json_write_object_end(w);
1288 
1289 	spdk_json_write_object_end(w);
1290 
1291 	for (i = 0; i < SPDK_COUNTOF(svdev->scsi_dev_state); i++) {
1292 		if (svdev->scsi_dev_state[i].dev == NULL || svdev->scsi_dev_state[i].removed) {
1293 			continue;
1294 		}
1295 
1296 		lun = spdk_scsi_dev_get_lun(svdev->scsi_dev_state[i].dev, 0);
1297 
1298 		spdk_json_write_object_begin(w);
1299 		spdk_json_write_named_string(w, "method", "add_vhost_scsi_lun");
1300 
1301 		spdk_json_write_named_object_begin(w, "params");
1302 		spdk_json_write_named_string(w, "ctrlr", vdev->name);
1303 		spdk_json_write_named_uint32(w, "scsi_target_num", i);
1304 
1305 		spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun));
1306 		spdk_json_write_object_end(w);
1307 
1308 		spdk_json_write_object_end(w);
1309 	}
1310 }
1311 
1312 SPDK_LOG_REGISTER_COMPONENT("vhost_scsi", SPDK_LOG_VHOST_SCSI)
1313 SPDK_LOG_REGISTER_COMPONENT("vhost_scsi_queue", SPDK_LOG_VHOST_SCSI_QUEUE)
1314 SPDK_LOG_REGISTER_COMPONENT("vhost_scsi_data", SPDK_LOG_VHOST_SCSI_DATA)
1315