1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2016 Jakub Klama <jceel@FreeBSD.org>.
5 * Copyright (c) 2018 Marcelo Araujo <araujo@FreeBSD.org>.
6 * Copyright (c) 2026 Hans Rosenfeld
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer
14 * in this position and unchanged.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #ifndef _PCI_VIRTIO_SCSI_H_
33 #define _PCI_VIRTIO_SCSI_H_
34
35 #include "iov.h"
36
37 extern int pci_vtscsi_debug;
38
39 #define WPRINTF(msg, params...) PRINTLN("virtio-scsi: " msg, ##params)
40 #define DPRINTF(msg, params...) if (pci_vtscsi_debug) WPRINTF(msg, ##params)
41
42 /* Absolute limits given by the VirtIO SCSI spec */
43 #define VIRTIO_SCSI_MAX_CHANNEL 0
44 #define VIRTIO_SCSI_MAX_TARGET 255
45 #define VIRTIO_SCSI_MAX_LUN 16383
46 #define VIRTIO_SCSI_HDR_SEG 2
47 #define VIRTIO_SCSI_ADDL_Q 2
48
49 /* Features specific to VirtIO SCSI, none of which we currently support */
50 #define VIRTIO_SCSI_F_INOUT (1 << 0)
51 #define VIRTIO_SCSI_F_HOTPLUG (1 << 1)
52 #define VIRTIO_SCSI_F_CHANGE (1 << 2)
53
54 /* Default limits which we set. All of these are configurable. */
55 #define VTSCSI_DEF_RINGSZ 64
56 #define VTSCSI_MIN_RINGSZ 4
57 #define VTSCSI_MAX_RINGSZ 4096
58
59 #define VTSCSI_DEF_THR_PER_Q 16
60 #define VTSCSI_MIN_THR_PER_Q 1
61 #define VTSCSI_MAX_THR_PER_Q 256
62
63 #define VTSCSI_DEF_MAXSEG 64
64 #define VTSCSI_MIN_MAXSEG (VIRTIO_SCSI_HDR_SEG + 1)
65 #define VTSCSI_MAX_MAXSEG \
66 (4096 - VIRTIO_SCSI_HDR_SEG - SPLIT_IOV_ADDL_IOV)
67
68 #define VTSCSI_DEF_REQUESTQ 1
69 #define VTSCSI_MIN_REQUESTQ 1
70 #define VTSCSI_MAX_REQUESTQ (32 - VIRTIO_SCSI_ADDL_Q)
71
72 /*
73 * Device-specific config space registers
74 *
75 * The guest driver may try to modify cdb_size and sense_size by writing the
76 * respective config space registers. Since we currently ignore all writes to
77 * config space, these macros are essentially constant.
78 */
79 #define VTSCSI_IN_HEADER_LEN(_sc) \
80 (sizeof(struct pci_vtscsi_req_cmd_rd) + _sc->vss_config.cdb_size)
81
82 #define VTSCSI_OUT_HEADER_LEN(_sc) \
83 (sizeof(struct pci_vtscsi_req_cmd_wr) + _sc->vss_config.sense_size)
84
85 struct pci_vtscsi_config {
86 uint32_t num_queues;
87 uint32_t seg_max;
88 uint32_t max_sectors;
89 uint32_t cmd_per_lun;
90 uint32_t event_info_size;
91 uint32_t sense_size;
92 uint32_t cdb_size;
93 uint16_t max_channel;
94 uint16_t max_target;
95 uint32_t max_lun;
96 } __attribute__((packed));
97
98
99 /*
100 * I/O request state and I/O request queues
101 *
102 * In addition to the control queue and notification queues, each virtio-scsi
103 * device instance has at least one I/O request queue, the state of which is
104 * is kept in an array of struct pci_vtscsi_queue in the device softc.
105 *
106 * Each pci_vtscsi_queue has configurable number of pci_vtscsi_request
107 * structures pre-allocated on vsq_free_requests. For each I/O request
108 * coming in on the I/O virtqueue, the request queue handler will take a
109 * pci_vtscsi_request off vsq_free_requests, fills in the data from the
110 * I/O virtqueue, puts it on vsq_requests, and signals vsq_cv.
111 *
112 * Each pci_vtscsi_queue will have a configurable number of worker threads,
113 * which wait on vsq_cv. When signalled, they repeatedly take a single
114 * pci_vtscsi_request off vsq_requests and hand it to the backend, which
115 * processes it synchronously. After completion, the pci_vtscsi_request
116 * is re-initialized and put back onto vsq_free_requests.
117 *
118 * The worker threads exit when vsq_cv is signalled after vsw_exiting was set.
119 *
120 * There are three mutexes to coordinate the accesses to an I/O request queue:
121 * - vsq_rmtx protects vsq_requests and must be held when waiting on vsq_cv
122 * - vsq_fmtx protects vsq_free_requests
123 * - vsq_qmtx must be held when operating on the underlying virtqueue, vsq_vq
124 *
125 * The I/O vectors for each request are kept in the preallocated iovec array
126 * vsr_iov, and pointers to the respective header/data in/out portions are set
127 * up to point into the array when the request is queued for processing.
128 *
129 * The number of iovecs preallocated for vsr_iov is derived from the configured
130 * 'seg_max' parameter defined by the virtio spec:
131 * - 'seg_max' parameter specifies the maximum number of I/O data vectors
132 * we support in any request
133 * - we need 2 additional iovecs for the I/O headers (VIRTIO_SCSI_HDR_SEG)
134 * - we need another 2 additional iovecs for split_iov() (SPLIT_IOV_ADDL_IOV)
135 *
136 * The only time we explicitly need the full size of vsr_iov after preallocation
137 * is during re-initialization after completing a request, and implicitly in the
138 * calls to split_iov() the set up the pointers. In all other cases, we use only
139 * 'seg_max' + VIRTIO_SCSI_HDR_SEG, and we advertise only 'seg_max' to the guest
140 * in accordance to the virtio spec.
141 */
142 STAILQ_HEAD(pci_vtscsi_req_queue, pci_vtscsi_request);
143
144 struct pci_vtscsi_queue {
145 struct pci_vtscsi_softc *vsq_sc;
146 struct vqueue_info *vsq_vq;
147 pthread_mutex_t vsq_rmtx;
148 pthread_mutex_t vsq_fmtx;
149 pthread_mutex_t vsq_qmtx;
150 pthread_cond_t vsq_cv;
151 struct pci_vtscsi_req_queue vsq_requests;
152 struct pci_vtscsi_req_queue vsq_free_requests;
153 LIST_HEAD(, pci_vtscsi_worker) vsq_workers;
154 };
155
156 struct pci_vtscsi_worker {
157 struct pci_vtscsi_queue *vsw_queue;
158 pthread_t vsw_thread;
159 bool vsw_exiting;
160 LIST_ENTRY(pci_vtscsi_worker) vsw_link;
161 };
162
163 struct pci_vtscsi_request {
164 struct pci_vtscsi_queue *vsr_queue;
165 struct iovec *vsr_iov;
166 struct iovec *vsr_iov_in;
167 struct iovec *vsr_iov_out;
168 struct iovec *vsr_data_iov_in;
169 struct iovec *vsr_data_iov_out;
170 struct pci_vtscsi_req_cmd_rd *vsr_cmd_rd;
171 struct pci_vtscsi_req_cmd_wr *vsr_cmd_wr;
172 void *vsr_backend;
173 size_t vsr_niov_in;
174 size_t vsr_niov_out;
175 size_t vsr_data_niov_in;
176 size_t vsr_data_niov_out;
177 uint32_t vsr_idx;
178 STAILQ_ENTRY(pci_vtscsi_request) vsr_link;
179 };
180
181 /*
182 * Per-target state.
183 */
184 struct pci_vtscsi_target {
185 uint8_t vst_target;
186 int vst_fd;
187 int vst_max_sectors;
188 };
189
190 /*
191 * Per-device softc
192 */
193 struct pci_vtscsi_softc {
194 struct virtio_softc vss_vs;
195 struct virtio_consts vss_vi_consts;
196 struct vqueue_info *vss_vq;
197 struct pci_vtscsi_queue *vss_queues;
198 pthread_mutex_t vss_mtx;
199 uint32_t vss_features;
200 size_t vss_num_target;
201 uint32_t vss_ctl_ringsz;
202 uint32_t vss_evt_ringsz;
203 uint32_t vss_req_ringsz;
204 uint32_t vss_thr_per_q;
205 struct pci_vtscsi_config vss_default_config;
206 struct pci_vtscsi_config vss_config;
207 struct pci_vtscsi_target *vss_targets;
208 struct pci_vtscsi_backend *vss_backend;
209 };
210
211 /*
212 * VirtIO-SCSI Task Management Function control requests
213 */
214 #define VIRTIO_SCSI_T_TMF 0
215 #define VIRTIO_SCSI_T_TMF_ABORT_TASK 0
216 #define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1
217 #define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2
218 #define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3
219 #define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4
220 #define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5
221 #define VIRTIO_SCSI_T_TMF_QUERY_TASK 6
222 #define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7
223
224 #define VIRTIO_SCSI_T_TMF_MAX_FUNC VIRTIO_SCSI_T_TMF_QUERY_TASK_SET
225
226 /* command-specific response values */
227 #define VIRTIO_SCSI_S_FUNCTION_COMPLETE 0
228 #define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10
229 #define VIRTIO_SCSI_S_FUNCTION_REJECTED 11
230
231 struct pci_vtscsi_ctrl_tmf {
232 const uint32_t type;
233 const uint32_t subtype;
234 const uint8_t lun[8];
235 const uint64_t id;
236 uint8_t response;
237 } __attribute__((packed));
238
239
240 /*
241 * VirtIO-SCSI Asynchronous Notification control requests
242 */
243 #define VIRTIO_SCSI_T_AN_QUERY 1
244 #define VIRTIO_SCSI_EVT_ASYNC_OPERATIONAL_CHANGE 2
245 #define VIRTIO_SCSI_EVT_ASYNC_POWER_MGMT 4
246 #define VIRTIO_SCSI_EVT_ASYNC_EXTERNAL_REQUEST 8
247 #define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE 16
248 #define VIRTIO_SCSI_EVT_ASYNC_MULTI_HOST 32
249 #define VIRTIO_SCSI_EVT_ASYNC_DEVICE_BUSY 64
250
251 struct pci_vtscsi_ctrl_an {
252 const uint32_t type;
253 const uint8_t lun[8];
254 const uint32_t event_requested;
255 uint32_t event_actual;
256 uint8_t response;
257 } __attribute__((packed));
258
259 /* command-specific response values */
260 #define VIRTIO_SCSI_S_OK 0
261 #define VIRTIO_SCSI_S_OVERRUN 1
262 #define VIRTIO_SCSI_S_ABORTED 2
263 #define VIRTIO_SCSI_S_BAD_TARGET 3
264 #define VIRTIO_SCSI_S_RESET 4
265 #define VIRTIO_SCSI_S_BUSY 5
266 #define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6
267 #define VIRTIO_SCSI_S_TARGET_FAILURE 7
268 #define VIRTIO_SCSI_S_NEXUS_FAILURE 8
269 #define VIRTIO_SCSI_S_FAILURE 9
270 #define VIRTIO_SCSI_S_INCORRECT_LUN 12
271
272 struct pci_vtscsi_event {
273 uint32_t event;
274 uint8_t lun[8];
275 uint32_t reason;
276 } __attribute__((packed));
277
278 /*
279 * VirtIO-SCSI I/O requests
280 */
281 struct pci_vtscsi_req_cmd_rd {
282 const uint8_t lun[8];
283 const uint64_t id;
284 const uint8_t task_attr;
285 const uint8_t prio;
286 const uint8_t crn;
287 const uint8_t cdb[];
288 } __attribute__((packed));
289
290 /* task_attr */
291 #define VIRTIO_SCSI_S_SIMPLE 0
292 #define VIRTIO_SCSI_S_ORDERED 1
293 #define VIRTIO_SCSI_S_HEAD 2
294 #define VIRTIO_SCSI_S_ACA 3
295
296 struct pci_vtscsi_req_cmd_wr {
297 uint32_t sense_len;
298 uint32_t residual;
299 uint16_t status_qualifier;
300 uint8_t status;
301 uint8_t response;
302 uint8_t sense[];
303 } __attribute__((packed));
304
305 /*
306 * Backend interface
307 */
308 struct pci_vtscsi_backend {
309 const char *vsb_name;
310 int (*vsb_init)(struct pci_vtscsi_softc *,
311 struct pci_vtscsi_backend *, nvlist_t *);
312 int (*vsb_open)(struct pci_vtscsi_softc *, const char *,
313 long);
314 void (*vsb_reset)(struct pci_vtscsi_softc *);
315
316 void* (*vsb_req_alloc)(struct pci_vtscsi_softc *);
317 void (*vsb_req_clear)(void *);
318 void (*vsb_req_free)(void *);
319
320 void (*vsb_tmf_hdl)(struct pci_vtscsi_softc *, int,
321 struct pci_vtscsi_ctrl_tmf *);
322 void (*vsb_an_hdl)(struct pci_vtscsi_softc *, int,
323 struct pci_vtscsi_ctrl_an *);
324 int (*vsb_req_hdl)(struct pci_vtscsi_softc *, int,
325 struct pci_vtscsi_request *);
326 };
327 #define PCI_VTSCSI_BACKEND_SET(x) DATA_SET(pci_vtscsi_backend_set, x)
328
329 /*
330 * LUN address parsing
331 *
332 * The LUN address consists of 8 bytes. While the spec describes this as 0x01,
333 * followed by the target byte, followed by a "single-level LUN structure",
334 * this is actually the same as a hierarchical LUN address as defined by SAM-5,
335 * consisting of four levels of addressing, where in each level the two MSB of
336 * byte 0 select the address mode used in the remaining bits and bytes.
337 *
338 *
339 * Only the first two levels are acutally used by virtio-scsi:
340 *
341 * Level 1: 0x01, 0xTT: Peripheral Device Addressing: Bus 1, Target 0-255
342 * Level 2: 0xLL, 0xLL: Peripheral Device Addressing: Bus MBZ, LUN 0-255
343 * or: Flat Space Addressing: LUN (0-16383)
344 * Level 3 and 4: not used, MBZ
345 *
346 *
347 * Alternatively, the first level may contain an extended LUN address to select
348 * the REPORT_LUNS well-known logical unit:
349 *
350 * Level 1: 0xC1, 0x01: Extended LUN Adressing, Well-Known LUN 1 (REPORT_LUNS)
351 * Level 2, 3, and 4: not used, MBZ
352 *
353 * The virtio spec says that we SHOULD implement the REPORT_LUNS well-known
354 * logical unit but we currently don't.
355 *
356 * According to the virtio spec, these are the only LUNS address formats to be
357 * used with virtio-scsi.
358 */
359
360 /*
361 * Check that the given LUN address conforms to the virtio spec, does not
362 * address an unknown target, and especially does not address the REPORT_LUNS
363 * well-known logical unit.
364 */
365 static inline bool
pci_vtscsi_check_lun(struct pci_vtscsi_softc * sc,const uint8_t * lun)366 pci_vtscsi_check_lun(struct pci_vtscsi_softc *sc, const uint8_t *lun)
367 {
368 if (lun[0] == 0xC1)
369 return (false);
370
371 if (lun[0] != 0x01)
372 return (false);
373
374 if (lun[1] >= sc->vss_num_target)
375 return (false);
376
377 if (lun[1] != sc->vss_targets[lun[1]].vst_target)
378 return (false);
379
380 if (sc->vss_targets[lun[1]].vst_fd < 0)
381 return (false);
382
383 if (lun[2] != 0x00 && (lun[2] & 0xc0) != 0x40)
384 return (false);
385
386 if (lun[4] != 0 || lun[5] != 0 || lun[6] != 0 || lun[7] != 0)
387 return (false);
388
389 return (true);
390 }
391
392 /*
393 * Get the target id from a LUN address.
394 *
395 * Every code path using this function must have called pci_vtscsi_check_lun()
396 * before to make sure the LUN address is valid.
397 */
398 static inline uint8_t
pci_vtscsi_get_target(struct pci_vtscsi_softc * sc,const uint8_t * lun)399 pci_vtscsi_get_target(struct pci_vtscsi_softc *sc, const uint8_t *lun)
400 {
401 assert(lun[0] == 0x01);
402 assert(lun[1] < sc->vss_num_target);
403 assert(lun[1] == sc->vss_targets[lun[1]].vst_target);
404 assert(sc->vss_targets[lun[1]].vst_fd >= 0);
405 assert(lun[2] == 0x00 || (lun[2] & 0xc0) == 0x40);
406
407 return (lun[1]);
408 }
409
410 /*
411 * Get the LUN id from a LUN address.
412 *
413 * Every code path using this function must have called pci_vtscsi_check_lun()
414 * before to make sure the LUN address is valid.
415 */
416 static inline uint16_t
pci_vtscsi_get_lun(struct pci_vtscsi_softc * sc,const uint8_t * lun)417 pci_vtscsi_get_lun(struct pci_vtscsi_softc *sc, const uint8_t *lun)
418 {
419 assert(lun[0] == 0x01);
420 assert(lun[1] < sc->vss_num_target);
421 assert(lun[1] == sc->vss_targets[lun[1]].vst_target);
422 assert(sc->vss_targets[lun[1]].vst_fd >= 0);
423 assert(lun[2] == 0x00 || (lun[2] & 0xc0) == 0x40);
424
425 return (((lun[2] << 8) | lun[3]) & 0x3fff);
426 }
427
428 #endif /* _PCI_VIRTIO_SCSI_H_ */
429