master
h 770 lines 19.8 KB
Raw
1 /*
2 * QEMU NVM Express
3 *
4 * Copyright (c) 2012 Intel Corporation
5 * Copyright (c) 2021 Minwoo Im
6 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
7 *
8 * Authors:
9 * Keith Busch <kbusch@kernel.org>
10 * Klaus Jensen <k.jensen@samsung.com>
11 * Gollu Appalanaidu <anaidu.gollu@samsung.com>
12 * Dmitry Fomichev <dmitry.fomichev@wdc.com>
13 * Minwoo Im <minwoo.im.dev@gmail.com>
14 *
15 * This code is licensed under the GNU GPL v2 or later.
16 */
17
18 #ifndef HW_NVME_NVME_H
19 #define HW_NVME_NVME_H
20
21 #include "qemu/uuid.h"
22 #include "hw/pci/pci_device.h"
23 #include "hw/block/block.h"
24
25 #include "block/nvme.h"
26
27 #define NVME_MAX_CONTROLLERS 256
28 #define NVME_MAX_NAMESPACES 256
29 #define NVME_EUI64_DEFAULT ((uint64_t)0x5254000000000000)
30 #define NVME_FDP_MAX_EVENTS 63
31 #define NVME_FDP_MAXPIDS 128
32
33 /*
34 * The controller only supports Submission and Completion Queue Entry Sizes of
35 * 64 and 16 bytes respectively.
36 */
37 #define NVME_SQES 6
38 #define NVME_CQES 4
39
40 QEMU_BUILD_BUG_ON(NVME_MAX_NAMESPACES > NVME_NSID_BROADCAST - 1);
41
42 typedef struct NvmeCtrl NvmeCtrl;
43 typedef struct NvmeNamespace NvmeNamespace;
44
45 #define TYPE_NVME_BUS "nvme-bus"
46 OBJECT_DECLARE_SIMPLE_TYPE(NvmeBus, NVME_BUS)
47
48 typedef struct NvmeBus {
49 BusState parent_bus;
50 } NvmeBus;
51
52 #define TYPE_NVME_SUBSYS "nvme-subsys"
53 #define NVME_SUBSYS(obj) \
54 OBJECT_CHECK(NvmeSubsystem, (obj), TYPE_NVME_SUBSYS)
55 #define SUBSYS_SLOT_RSVD (void *)0xFFFF
56
57 typedef struct NvmeReclaimUnit {
58 uint64_t ruamw;
59 } NvmeReclaimUnit;
60
61 typedef struct NvmeRuHandle {
62 uint8_t ruht;
63 uint8_t ruha;
64 uint64_t event_filter;
65 uint8_t lbafi;
66 uint64_t ruamw;
67
68 /* reclaim units indexed by reclaim group */
69 NvmeReclaimUnit *rus;
70 } NvmeRuHandle;
71
72 typedef struct NvmeFdpEventBuffer {
73 NvmeFdpEvent events[NVME_FDP_MAX_EVENTS];
74 unsigned int nelems;
75 unsigned int start;
76 unsigned int next;
77 } NvmeFdpEventBuffer;
78
79 typedef struct NvmeEnduranceGroup {
80 uint8_t event_conf;
81
82 struct {
83 NvmeFdpEventBuffer host_events, ctrl_events;
84
85 uint16_t nruh;
86 uint16_t nrg;
87 uint8_t rgif;
88 uint64_t runs;
89
90 uint64_t hbmw;
91 uint64_t mbmw;
92 uint64_t mbe;
93
94 bool enabled;
95
96 NvmeRuHandle *ruhs;
97 } fdp;
98 } NvmeEnduranceGroup;
99
100 typedef struct NvmeSubsystem {
101 DeviceState parent_obj;
102 NvmeBus bus;
103 uint8_t subnqn[256];
104 char *serial;
105
106 NvmeCtrl *ctrls[NVME_MAX_CONTROLLERS];
107 NvmeNamespace *namespaces[NVME_MAX_NAMESPACES + 1];
108 NvmeEnduranceGroup endgrp;
109
110 struct {
111 char *nqn;
112
113 struct {
114 bool enabled;
115 uint64_t runs;
116 uint16_t nruh;
117 uint32_t nrg;
118 } fdp;
119 } params;
120 } NvmeSubsystem;
121
122 int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp);
123 void nvme_subsys_unregister_ctrl(NvmeSubsystem *subsys, NvmeCtrl *n);
124
125 static inline NvmeCtrl *nvme_subsys_ctrl(NvmeSubsystem *subsys,
126 uint32_t cntlid)
127 {
128 if (!subsys || cntlid >= NVME_MAX_CONTROLLERS) {
129 return NULL;
130 }
131
132 if (subsys->ctrls[cntlid] == SUBSYS_SLOT_RSVD) {
133 return NULL;
134 }
135
136 return subsys->ctrls[cntlid];
137 }
138
139 static inline NvmeNamespace *nvme_subsys_ns(NvmeSubsystem *subsys,
140 uint32_t nsid)
141 {
142 if (!subsys || !nsid || nsid > NVME_MAX_NAMESPACES) {
143 return NULL;
144 }
145
146 return subsys->namespaces[nsid];
147 }
148
149 #define TYPE_NVME_NS "nvme-ns"
150 #define NVME_NS(obj) \
151 OBJECT_CHECK(NvmeNamespace, (obj), TYPE_NVME_NS)
152
153 typedef struct NvmeZone {
154 NvmeZoneDescr d;
155 uint64_t w_ptr;
156 QTAILQ_ENTRY(NvmeZone) entry;
157 } NvmeZone;
158
159 #define FDP_EVT_MAX 0xff
160 #define NVME_FDP_MAX_NS_RUHS 32u
161 #define FDPVSS 0
162
163 /*
164 * NOTE: Apart from event type 0, any event type with a shift value of 0 is
165 * considered unsupported and thus skipped in get/set features calls.
166 *
167 * NOTE: NvmeRuHandle uses a 64bit event mask - refactor to support event types
168 * of 63 or greater.
169 */
170 static const uint8_t nvme_fdp_evf_shifts[FDP_EVT_MAX + 1] = {
171 /* Host events */
172 [FDP_EVT_RU_NOT_FULLY_WRITTEN] = 0,
173 [FDP_EVT_RU_ATL_EXCEEDED] = 1,
174 [FDP_EVT_CTRL_RESET_RUH] = 2,
175 [FDP_EVT_INVALID_PID] = 3,
176 /* CTRL events */
177 [FDP_EVT_MEDIA_REALLOC] = 32,
178 [FDP_EVT_RUH_IMPLICIT_RU_CHANGE] = 33,
179 };
180
181 #define NGUID_LEN 16
182
183 typedef struct {
184 uint8_t data[NGUID_LEN];
185 } NvmeNGUID;
186
187 bool nvme_nguid_is_null(const NvmeNGUID *nguid);
188
189 extern const PropertyInfo qdev_prop_nguid;
190
191 #define DEFINE_PROP_NGUID_NODEFAULT(_name, _state, _field) \
192 DEFINE_PROP(_name, _state, _field, qdev_prop_nguid, NvmeNGUID)
193
194 typedef struct NvmeNamespaceParams {
195 bool detached;
196 bool shared;
197 uint32_t nsid;
198 QemuUUID uuid;
199 NvmeNGUID nguid;
200 uint64_t eui64;
201 bool eui64_default;
202
203 uint16_t ms;
204 uint8_t mset;
205 uint8_t pi;
206 uint8_t pil;
207 uint8_t pif;
208
209 uint16_t mssrl;
210 uint32_t mcl;
211 uint8_t msrc;
212
213 bool zoned;
214 bool cross_zone_read;
215 uint64_t zone_size_bs;
216 uint64_t zone_cap_bs;
217 uint32_t max_active_zones;
218 uint32_t max_open_zones;
219 uint32_t zd_extension_size;
220
221 uint32_t numzrwa;
222 uint64_t zrwas;
223 uint64_t zrwafg;
224
225 struct {
226 char *ruhs;
227 } fdp;
228
229 struct {
230 uint16_t nawun;
231 uint16_t nawupf;
232 uint16_t nabsn;
233 uint16_t nabspf;
234 uint16_t nabo;
235 } atomic;
236 } NvmeNamespaceParams;
237
238 typedef struct NvmeAtomic {
239 uint32_t atomic_max_write_size;
240 uint64_t atomic_boundary;
241 uint64_t atomic_nabo;
242 bool atomic_writes;
243 } NvmeAtomic;
244
245 typedef struct NvmeNamespace {
246 DeviceState parent_obj;
247 BlockConf blkconf;
248 int32_t bootindex;
249 char bootindex_suffix[24];
250 int64_t size;
251 int64_t moff;
252 NvmeIdNs id_ns;
253 NvmeIdNsNvm id_ns_nvm;
254 NvmeIdNsInd id_ns_ind;
255 NvmeLBAF lbaf;
256 unsigned int nlbaf;
257 size_t lbasz;
258 uint8_t csi;
259 uint16_t status;
260 int attached;
261 uint8_t pif;
262
263 struct {
264 uint16_t zrwas;
265 uint16_t zrwafg;
266 uint32_t numzrwa;
267 } zns;
268
269 QTAILQ_ENTRY(NvmeNamespace) entry;
270
271 NvmeIdNsZoned *id_ns_zoned;
272 NvmeZone *zone_array;
273 QTAILQ_HEAD(, NvmeZone) exp_open_zones;
274 QTAILQ_HEAD(, NvmeZone) imp_open_zones;
275 QTAILQ_HEAD(, NvmeZone) closed_zones;
276 QTAILQ_HEAD(, NvmeZone) full_zones;
277 uint32_t num_zones;
278 uint64_t zone_size;
279 uint64_t zone_capacity;
280 uint32_t zone_size_log2;
281 uint8_t *zd_extensions;
282 int32_t nr_open_zones;
283 int32_t nr_active_zones;
284
285 NvmeNamespaceParams params;
286 NvmeSubsystem *subsys;
287 NvmeEnduranceGroup *endgrp;
288
289 /* NULL for shared namespaces; set to specific controller if private */
290 NvmeCtrl *ctrl;
291
292 struct {
293 uint32_t err_rec;
294 } features;
295
296 struct {
297 uint16_t nphs;
298 /* reclaim unit handle identifiers indexed by placement handle */
299 uint16_t *phs;
300 } fdp;
301
302 NvmeAtomic atomic;
303 } NvmeNamespace;
304
305 static inline uint32_t nvme_nsid(NvmeNamespace *ns)
306 {
307 if (ns) {
308 return ns->params.nsid;
309 }
310
311 return 0;
312 }
313
314 static inline size_t nvme_l2b(NvmeNamespace *ns, uint64_t lba)
315 {
316 return lba << ns->lbaf.ds;
317 }
318
319 static inline size_t nvme_m2b(NvmeNamespace *ns, uint64_t lba)
320 {
321 return ns->lbaf.ms * lba;
322 }
323
324 static inline int64_t nvme_moff(NvmeNamespace *ns, uint64_t lba)
325 {
326 return ns->moff + nvme_m2b(ns, lba);
327 }
328
329 static inline bool nvme_ns_ext(NvmeNamespace *ns)
330 {
331 return !!NVME_ID_NS_FLBAS_EXTENDED(ns->id_ns.flbas);
332 }
333
334 static inline NvmeZoneState nvme_get_zone_state(NvmeZone *zone)
335 {
336 return zone->d.zs >> 4;
337 }
338
339 static inline void nvme_set_zone_state(NvmeZone *zone, NvmeZoneState state)
340 {
341 zone->d.zs = state << 4;
342 }
343
344 static inline uint64_t nvme_zone_rd_boundary(NvmeNamespace *ns, NvmeZone *zone)
345 {
346 return zone->d.zslba + ns->zone_size;
347 }
348
349 static inline uint64_t nvme_zone_wr_boundary(NvmeZone *zone)
350 {
351 return zone->d.zslba + zone->d.zcap;
352 }
353
354 static inline bool nvme_wp_is_valid(NvmeZone *zone)
355 {
356 uint8_t st = nvme_get_zone_state(zone);
357
358 return st != NVME_ZONE_STATE_FULL &&
359 st != NVME_ZONE_STATE_READ_ONLY &&
360 st != NVME_ZONE_STATE_OFFLINE;
361 }
362
363 static inline uint8_t *nvme_get_zd_extension(NvmeNamespace *ns,
364 uint32_t zone_idx)
365 {
366 return &ns->zd_extensions[zone_idx * ns->params.zd_extension_size];
367 }
368
369 static inline void nvme_aor_inc_open(NvmeNamespace *ns)
370 {
371 assert(ns->nr_open_zones >= 0);
372 if (ns->params.max_open_zones) {
373 ns->nr_open_zones++;
374 assert(ns->nr_open_zones <= ns->params.max_open_zones);
375 }
376 }
377
378 static inline void nvme_aor_dec_open(NvmeNamespace *ns)
379 {
380 if (ns->params.max_open_zones) {
381 assert(ns->nr_open_zones > 0);
382 ns->nr_open_zones--;
383 }
384 assert(ns->nr_open_zones >= 0);
385 }
386
387 static inline void nvme_aor_inc_active(NvmeNamespace *ns)
388 {
389 assert(ns->nr_active_zones >= 0);
390 if (ns->params.max_active_zones) {
391 ns->nr_active_zones++;
392 assert(ns->nr_active_zones <= ns->params.max_active_zones);
393 }
394 }
395
396 static inline void nvme_aor_dec_active(NvmeNamespace *ns)
397 {
398 if (ns->params.max_active_zones) {
399 assert(ns->nr_active_zones > 0);
400 ns->nr_active_zones--;
401 assert(ns->nr_active_zones >= ns->nr_open_zones);
402 }
403 assert(ns->nr_active_zones >= 0);
404 }
405
406 static inline void nvme_fdp_stat_inc(uint64_t *a, uint64_t b)
407 {
408 uint64_t ret = *a + b;
409 *a = ret < *a ? UINT64_MAX : ret;
410 }
411
412 void nvme_ns_init_format(NvmeNamespace *ns);
413 int nvme_ns_setup(NvmeNamespace *ns, Error **errp);
414 void nvme_ns_drain(NvmeNamespace *ns);
415 void nvme_ns_shutdown(NvmeNamespace *ns);
416 void nvme_ns_cleanup(NvmeNamespace *ns);
417
418 typedef struct NvmeAsyncEvent {
419 QTAILQ_ENTRY(NvmeAsyncEvent) entry;
420 NvmeAerResult result;
421 } NvmeAsyncEvent;
422
423 enum {
424 NVME_SG_ALLOC = 1 << 0,
425 NVME_SG_DMA = 1 << 1,
426 };
427
428 typedef struct NvmeSg {
429 int flags;
430
431 union {
432 QEMUSGList qsg;
433 QEMUIOVector iov;
434 };
435 } NvmeSg;
436
437 typedef enum NvmeTxDirection {
438 NVME_TX_DIRECTION_TO_DEVICE = 0,
439 NVME_TX_DIRECTION_FROM_DEVICE = 1,
440 } NvmeTxDirection;
441
442 typedef struct NvmeRequest {
443 struct NvmeSQueue *sq;
444 struct NvmeNamespace *ns;
445 BlockAIOCB *aiocb;
446 uint16_t status;
447 void *opaque;
448 NvmeCqe cqe;
449 NvmeCmd cmd;
450 BlockAcctCookie acct;
451 NvmeSg sg;
452 bool atomic_write;
453 QTAILQ_ENTRY(NvmeRequest)entry;
454 /*
455 * If you add a new field here, please make sure to update
456 * nvme_vmstate_request, pre_save_validate_aer_req() and
457 * pre_save_validate_cq_req().
458 */
459 } NvmeRequest;
460
461 typedef struct NvmeBounceContext {
462 NvmeRequest *req;
463
464 struct {
465 QEMUIOVector iov;
466 uint8_t *bounce;
467 } data, mdata;
468 } NvmeBounceContext;
469
470 static inline const char *nvme_adm_opc_str(uint8_t opc)
471 {
472 switch (opc) {
473 case NVME_ADM_CMD_DELETE_SQ: return "NVME_ADM_CMD_DELETE_SQ";
474 case NVME_ADM_CMD_CREATE_SQ: return "NVME_ADM_CMD_CREATE_SQ";
475 case NVME_ADM_CMD_GET_LOG_PAGE: return "NVME_ADM_CMD_GET_LOG_PAGE";
476 case NVME_ADM_CMD_DELETE_CQ: return "NVME_ADM_CMD_DELETE_CQ";
477 case NVME_ADM_CMD_CREATE_CQ: return "NVME_ADM_CMD_CREATE_CQ";
478 case NVME_ADM_CMD_IDENTIFY: return "NVME_ADM_CMD_IDENTIFY";
479 case NVME_ADM_CMD_ABORT: return "NVME_ADM_CMD_ABORT";
480 case NVME_ADM_CMD_SET_FEATURES: return "NVME_ADM_CMD_SET_FEATURES";
481 case NVME_ADM_CMD_GET_FEATURES: return "NVME_ADM_CMD_GET_FEATURES";
482 case NVME_ADM_CMD_ASYNC_EV_REQ: return "NVME_ADM_CMD_ASYNC_EV_REQ";
483 case NVME_ADM_CMD_NS_ATTACHMENT: return "NVME_ADM_CMD_NS_ATTACHMENT";
484 case NVME_ADM_CMD_DIRECTIVE_SEND: return "NVME_ADM_CMD_DIRECTIVE_SEND";
485 case NVME_ADM_CMD_VIRT_MNGMT: return "NVME_ADM_CMD_VIRT_MNGMT";
486 case NVME_ADM_CMD_DIRECTIVE_RECV: return "NVME_ADM_CMD_DIRECTIVE_RECV";
487 case NVME_ADM_CMD_DBBUF_CONFIG: return "NVME_ADM_CMD_DBBUF_CONFIG";
488 case NVME_ADM_CMD_FORMAT_NVM: return "NVME_ADM_CMD_FORMAT_NVM";
489 case NVME_ADM_CMD_SECURITY_SEND: return "NVME_ADM_CMD_SECURITY_SEND";
490 case NVME_ADM_CMD_SECURITY_RECV: return "NVME_ADM_CMD_SECURITY_RECV";
491 default: return "NVME_ADM_CMD_UNKNOWN";
492 }
493 }
494
495 static inline const char *nvme_io_opc_str(uint8_t opc)
496 {
497 switch (opc) {
498 case NVME_CMD_FLUSH: return "NVME_NVM_CMD_FLUSH";
499 case NVME_CMD_WRITE: return "NVME_NVM_CMD_WRITE";
500 case NVME_CMD_READ: return "NVME_NVM_CMD_READ";
501 case NVME_CMD_COMPARE: return "NVME_NVM_CMD_COMPARE";
502 case NVME_CMD_WRITE_ZEROES: return "NVME_NVM_CMD_WRITE_ZEROES";
503 case NVME_CMD_DSM: return "NVME_NVM_CMD_DSM";
504 case NVME_CMD_VERIFY: return "NVME_NVM_CMD_VERIFY";
505 case NVME_CMD_COPY: return "NVME_NVM_CMD_COPY";
506 case NVME_CMD_ZONE_MGMT_SEND: return "NVME_ZONED_CMD_MGMT_SEND";
507 case NVME_CMD_ZONE_MGMT_RECV: return "NVME_ZONED_CMD_MGMT_RECV";
508 case NVME_CMD_ZONE_APPEND: return "NVME_ZONED_CMD_ZONE_APPEND";
509 default: return "NVME_NVM_CMD_UNKNOWN";
510 }
511 }
512
513 typedef struct NvmeSQueue {
514 struct NvmeCtrl *ctrl;
515 uint16_t sqid;
516 uint16_t cqid;
517 uint32_t head;
518 uint32_t tail;
519 uint32_t size;
520 uint64_t dma_addr;
521 uint64_t db_addr;
522 uint64_t ei_addr;
523 QEMUBH *bh;
524 EventNotifier notifier;
525 bool ioeventfd_enabled;
526 NvmeRequest *io_req;
527 QTAILQ_HEAD(, NvmeRequest) req_list;
528 QTAILQ_HEAD(, NvmeRequest) out_req_list;
529 QTAILQ_ENTRY(NvmeSQueue) entry;
530 } NvmeSQueue;
531
532 typedef struct NvmeCQueue {
533 struct NvmeCtrl *ctrl;
534 uint8_t phase;
535 uint16_t cqid;
536 uint16_t irq_enabled;
537 uint32_t head;
538 uint32_t tail;
539 uint32_t vector;
540 uint32_t size;
541 uint64_t dma_addr;
542 uint64_t db_addr;
543 uint64_t ei_addr;
544 QEMUBH *bh;
545 EventNotifier notifier;
546 bool ioeventfd_enabled;
547 QTAILQ_HEAD(, NvmeSQueue) sq_list;
548 QTAILQ_HEAD(, NvmeRequest) req_list;
549 } NvmeCQueue;
550
551 #define TYPE_NVME "nvme"
552 #define NVME(obj) \
553 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
554
555 typedef struct NvmeParams {
556 char *serial;
557 char *model;
558 char *firmware_version;
559 uint32_t num_queues; /* deprecated since 5.1 */
560 uint32_t max_ioqpairs;
561 uint16_t msix_qsize;
562 uint16_t mqes;
563 uint32_t cmb_size_mb;
564 uint8_t aerl;
565 uint32_t aer_max_queued;
566 uint8_t mdts;
567 uint8_t vsl;
568 bool use_intel_id;
569 uint8_t zasl;
570 bool auto_transition_zones;
571 bool legacy_cmb;
572 bool ioeventfd;
573 bool dbcs;
574 uint16_t sriov_max_vfs;
575 uint16_t sriov_vq_flexible;
576 uint16_t sriov_vi_flexible;
577 uint32_t sriov_max_vq_per_vf;
578 uint32_t sriov_max_vi_per_vf;
579 bool msix_exclusive_bar;
580 bool ocp;
581
582 struct {
583 bool mem;
584 } ctratt;
585
586 uint16_t atomic_awun;
587 uint16_t atomic_awupf;
588 bool atomic_dn;
589 } NvmeParams;
590
591 typedef struct NvmeCtrl {
592 PCIDevice parent_obj;
593 MemoryRegion bar0;
594 MemoryRegion iomem;
595 NvmeBar bar;
596 NvmeParams params;
597 NvmeBus bus;
598
599 uint16_t cntlid;
600 bool qs_created;
601 uint32_t page_size;
602 uint16_t page_bits;
603 uint16_t max_prp_ents;
604 uint32_t max_q_ents;
605 uint8_t outstanding_aers;
606 uint32_t irq_status;
607 int cq_pending;
608 uint64_t host_timestamp; /* Timestamp sent by the host */
609 uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
610 uint64_t starttime_ms;
611 uint16_t temperature;
612 uint8_t smart_critical_warning;
613 uint32_t conf_msix_qsize;
614 uint32_t conf_ioqpairs;
615 uint64_t dbbuf_dbs;
616 uint64_t dbbuf_eis;
617 bool dbbuf_enabled;
618
619 struct {
620 uint32_t acs[256];
621 struct {
622 uint32_t nvm[256];
623 uint32_t zoned[256];
624 } iocs;
625 } cse;
626
627 struct {
628 MemoryRegion mem;
629 uint8_t *buf;
630 bool cmse;
631 hwaddr cba;
632 } cmb;
633
634 struct {
635 HostMemoryBackend *dev;
636 bool cmse;
637 hwaddr cba;
638 } pmr;
639
640 uint8_t aer_mask;
641 NvmeRequest **aer_reqs;
642 QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
643 int aer_queued;
644
645 uint32_t dmrsl;
646
647 /* Namespace ID is started with 1 so bitmap should be 1-based */
648 #define NVME_CHANGED_NSID_SIZE (NVME_MAX_NAMESPACES + 1)
649 DECLARE_BITMAP(changed_nsids, NVME_CHANGED_NSID_SIZE);
650
651 NvmeSubsystem *subsys;
652
653 NvmeNamespace namespace;
654 NvmeNamespace *namespaces[NVME_MAX_NAMESPACES + 1];
655 uint32_t num_queues;
656 NvmeSQueue **sq;
657 NvmeCQueue **cq;
658 NvmeSQueue admin_sq;
659 NvmeCQueue admin_cq;
660 NvmeIdCtrl id_ctrl;
661
662 struct {
663 struct {
664 uint16_t temp_thresh_hi;
665 uint16_t temp_thresh_low;
666 };
667
668 uint32_t async_config;
669 NvmeHostBehaviorSupport hbs;
670 } features;
671
672 NvmePriCtrlCap pri_ctrl_cap;
673 uint32_t nr_sec_ctrls;
674 NvmeSecCtrlEntry *sec_ctrl_list;
675 struct {
676 uint16_t vqrfap;
677 uint16_t virfap;
678 } next_pri_ctrl_cap; /* These override pri_ctrl_cap after reset */
679 uint32_t dn; /* Disable Normal */
680 NvmeAtomic atomic;
681
682 /* Socket mapping to SPDM over NVMe Security In/Out commands */
683 int spdm_socket;
684
685 /* Migration-related stuff */
686 Error *migration_blocker;
687 } NvmeCtrl;
688
689 typedef enum NvmeResetType {
690 NVME_RESET_FUNCTION = 0,
691 NVME_RESET_CONTROLLER = 1,
692 } NvmeResetType;
693
694 static inline NvmeNamespace *nvme_ns(NvmeCtrl *n, uint32_t nsid)
695 {
696 if (!nsid || nsid > NVME_MAX_NAMESPACES) {
697 return NULL;
698 }
699
700 return n->namespaces[nsid];
701 }
702
703 static inline NvmeCQueue *nvme_cq(NvmeRequest *req)
704 {
705 NvmeSQueue *sq = req->sq;
706 NvmeCtrl *n = sq->ctrl;
707
708 return n->cq[sq->cqid];
709 }
710
711 static inline NvmeCtrl *nvme_ctrl(NvmeRequest *req)
712 {
713 NvmeSQueue *sq = req->sq;
714 return sq->ctrl;
715 }
716
717 static inline uint16_t nvme_cid(NvmeRequest *req)
718 {
719 if (!req) {
720 return 0xffff;
721 }
722
723 return le16_to_cpu(req->cqe.cid);
724 }
725
726 static inline NvmeSecCtrlEntry *nvme_sctrl(NvmeCtrl *n)
727 {
728 PCIDevice *pci_dev = &n->parent_obj;
729 NvmeCtrl *pf = NVME(pcie_sriov_get_pf(pci_dev));
730
731 if (pci_is_vf(pci_dev)) {
732 return &pf->sec_ctrl_list[pcie_sriov_vf_number(pci_dev)];
733 }
734
735 return NULL;
736 }
737
738 static inline NvmeSecCtrlEntry *nvme_sctrl_for_cntlid(NvmeCtrl *n,
739 uint16_t cntlid)
740 {
741 NvmeSecCtrlEntry *list = n->sec_ctrl_list;
742 uint8_t i;
743
744 for (i = 0; i < n->nr_sec_ctrls; i++) {
745 if (le16_to_cpu(list[i].scid) == cntlid) {
746 return &list[i];
747 }
748 }
749
750 return NULL;
751 }
752
753 void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns);
754 uint16_t nvme_bounce_data(NvmeCtrl *n, void *ptr, uint32_t len,
755 NvmeTxDirection dir, NvmeRequest *req);
756 uint16_t nvme_bounce_mdata(NvmeCtrl *n, void *ptr, uint32_t len,
757 NvmeTxDirection dir, NvmeRequest *req);
758 void nvme_rw_complete_cb(void *opaque, int ret);
759 uint16_t nvme_map_dptr(NvmeCtrl *n, NvmeSg *sg, size_t len,
760 NvmeCmd *cmd);
761
762 void nvme_atomic_configure_max_write_size(bool dn, uint16_t awun,
763 uint16_t awupf, NvmeAtomic *atomic);
764 void nvme_ns_atomic_configure_boundary(bool dn, uint16_t nabsn,
765 uint16_t nabspf, NvmeAtomic *atomic);
766
767 extern const VMStateDescription nvme_vmstate_atomic;
768 extern const VMStateDescription nvme_vmstate_ns;
769
770 #endif /* HW_NVME_NVME_H */