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
nvme_subsys_ctrl(NvmeSubsystem * subsys,uint32_t cntlid)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
nvme_subsys_ns(NvmeSubsystem * subsys,uint32_t nsid)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 static const uint8_t nvme_fdp_evf_shifts[FDP_EVT_MAX] = {
164 /* Host events */
165 [FDP_EVT_RU_NOT_FULLY_WRITTEN] = 0,
166 [FDP_EVT_RU_ATL_EXCEEDED] = 1,
167 [FDP_EVT_CTRL_RESET_RUH] = 2,
168 [FDP_EVT_INVALID_PID] = 3,
169 /* CTRL events */
170 [FDP_EVT_MEDIA_REALLOC] = 32,
171 [FDP_EVT_RUH_IMPLICIT_RU_CHANGE] = 33,
172 };
173
174 #define NGUID_LEN 16
175
176 typedef struct {
177 uint8_t data[NGUID_LEN];
178 } NvmeNGUID;
179
180 bool nvme_nguid_is_null(const NvmeNGUID *nguid);
181
182 extern const PropertyInfo qdev_prop_nguid;
183
184 #define DEFINE_PROP_NGUID_NODEFAULT(_name, _state, _field) \
185 DEFINE_PROP(_name, _state, _field, qdev_prop_nguid, NvmeNGUID)
186
187 typedef struct NvmeNamespaceParams {
188 bool detached;
189 bool shared;
190 uint32_t nsid;
191 QemuUUID uuid;
192 NvmeNGUID nguid;
193 uint64_t eui64;
194 bool eui64_default;
195
196 uint16_t ms;
197 uint8_t mset;
198 uint8_t pi;
199 uint8_t pil;
200 uint8_t pif;
201
202 uint16_t mssrl;
203 uint32_t mcl;
204 uint8_t msrc;
205
206 bool zoned;
207 bool cross_zone_read;
208 uint64_t zone_size_bs;
209 uint64_t zone_cap_bs;
210 uint32_t max_active_zones;
211 uint32_t max_open_zones;
212 uint32_t zd_extension_size;
213
214 uint32_t numzrwa;
215 uint64_t zrwas;
216 uint64_t zrwafg;
217
218 struct {
219 char *ruhs;
220 } fdp;
221 } NvmeNamespaceParams;
222
223 typedef struct NvmeNamespace {
224 DeviceState parent_obj;
225 BlockConf blkconf;
226 int32_t bootindex;
227 int64_t size;
228 int64_t moff;
229 NvmeIdNs id_ns;
230 NvmeIdNsNvm id_ns_nvm;
231 NvmeLBAF lbaf;
232 unsigned int nlbaf;
233 size_t lbasz;
234 const uint32_t *iocs;
235 uint8_t csi;
236 uint16_t status;
237 int attached;
238 uint8_t pif;
239
240 struct {
241 uint16_t zrwas;
242 uint16_t zrwafg;
243 uint32_t numzrwa;
244 } zns;
245
246 QTAILQ_ENTRY(NvmeNamespace) entry;
247
248 NvmeIdNsZoned *id_ns_zoned;
249 NvmeZone *zone_array;
250 QTAILQ_HEAD(, NvmeZone) exp_open_zones;
251 QTAILQ_HEAD(, NvmeZone) imp_open_zones;
252 QTAILQ_HEAD(, NvmeZone) closed_zones;
253 QTAILQ_HEAD(, NvmeZone) full_zones;
254 uint32_t num_zones;
255 uint64_t zone_size;
256 uint64_t zone_capacity;
257 uint32_t zone_size_log2;
258 uint8_t *zd_extensions;
259 int32_t nr_open_zones;
260 int32_t nr_active_zones;
261
262 NvmeNamespaceParams params;
263 NvmeSubsystem *subsys;
264 NvmeEnduranceGroup *endgrp;
265
266 struct {
267 uint32_t err_rec;
268 } features;
269
270 struct {
271 uint16_t nphs;
272 /* reclaim unit handle identifiers indexed by placement handle */
273 uint16_t *phs;
274 } fdp;
275 } NvmeNamespace;
276
nvme_nsid(NvmeNamespace * ns)277 static inline uint32_t nvme_nsid(NvmeNamespace *ns)
278 {
279 if (ns) {
280 return ns->params.nsid;
281 }
282
283 return 0;
284 }
285
nvme_l2b(NvmeNamespace * ns,uint64_t lba)286 static inline size_t nvme_l2b(NvmeNamespace *ns, uint64_t lba)
287 {
288 return lba << ns->lbaf.ds;
289 }
290
nvme_m2b(NvmeNamespace * ns,uint64_t lba)291 static inline size_t nvme_m2b(NvmeNamespace *ns, uint64_t lba)
292 {
293 return ns->lbaf.ms * lba;
294 }
295
nvme_moff(NvmeNamespace * ns,uint64_t lba)296 static inline int64_t nvme_moff(NvmeNamespace *ns, uint64_t lba)
297 {
298 return ns->moff + nvme_m2b(ns, lba);
299 }
300
nvme_ns_ext(NvmeNamespace * ns)301 static inline bool nvme_ns_ext(NvmeNamespace *ns)
302 {
303 return !!NVME_ID_NS_FLBAS_EXTENDED(ns->id_ns.flbas);
304 }
305
nvme_get_zone_state(NvmeZone * zone)306 static inline NvmeZoneState nvme_get_zone_state(NvmeZone *zone)
307 {
308 return zone->d.zs >> 4;
309 }
310
nvme_set_zone_state(NvmeZone * zone,NvmeZoneState state)311 static inline void nvme_set_zone_state(NvmeZone *zone, NvmeZoneState state)
312 {
313 zone->d.zs = state << 4;
314 }
315
nvme_zone_rd_boundary(NvmeNamespace * ns,NvmeZone * zone)316 static inline uint64_t nvme_zone_rd_boundary(NvmeNamespace *ns, NvmeZone *zone)
317 {
318 return zone->d.zslba + ns->zone_size;
319 }
320
nvme_zone_wr_boundary(NvmeZone * zone)321 static inline uint64_t nvme_zone_wr_boundary(NvmeZone *zone)
322 {
323 return zone->d.zslba + zone->d.zcap;
324 }
325
nvme_wp_is_valid(NvmeZone * zone)326 static inline bool nvme_wp_is_valid(NvmeZone *zone)
327 {
328 uint8_t st = nvme_get_zone_state(zone);
329
330 return st != NVME_ZONE_STATE_FULL &&
331 st != NVME_ZONE_STATE_READ_ONLY &&
332 st != NVME_ZONE_STATE_OFFLINE;
333 }
334
nvme_get_zd_extension(NvmeNamespace * ns,uint32_t zone_idx)335 static inline uint8_t *nvme_get_zd_extension(NvmeNamespace *ns,
336 uint32_t zone_idx)
337 {
338 return &ns->zd_extensions[zone_idx * ns->params.zd_extension_size];
339 }
340
nvme_aor_inc_open(NvmeNamespace * ns)341 static inline void nvme_aor_inc_open(NvmeNamespace *ns)
342 {
343 assert(ns->nr_open_zones >= 0);
344 if (ns->params.max_open_zones) {
345 ns->nr_open_zones++;
346 assert(ns->nr_open_zones <= ns->params.max_open_zones);
347 }
348 }
349
nvme_aor_dec_open(NvmeNamespace * ns)350 static inline void nvme_aor_dec_open(NvmeNamespace *ns)
351 {
352 if (ns->params.max_open_zones) {
353 assert(ns->nr_open_zones > 0);
354 ns->nr_open_zones--;
355 }
356 assert(ns->nr_open_zones >= 0);
357 }
358
nvme_aor_inc_active(NvmeNamespace * ns)359 static inline void nvme_aor_inc_active(NvmeNamespace *ns)
360 {
361 assert(ns->nr_active_zones >= 0);
362 if (ns->params.max_active_zones) {
363 ns->nr_active_zones++;
364 assert(ns->nr_active_zones <= ns->params.max_active_zones);
365 }
366 }
367
nvme_aor_dec_active(NvmeNamespace * ns)368 static inline void nvme_aor_dec_active(NvmeNamespace *ns)
369 {
370 if (ns->params.max_active_zones) {
371 assert(ns->nr_active_zones > 0);
372 ns->nr_active_zones--;
373 assert(ns->nr_active_zones >= ns->nr_open_zones);
374 }
375 assert(ns->nr_active_zones >= 0);
376 }
377
nvme_fdp_stat_inc(uint64_t * a,uint64_t b)378 static inline void nvme_fdp_stat_inc(uint64_t *a, uint64_t b)
379 {
380 uint64_t ret = *a + b;
381 *a = ret < *a ? UINT64_MAX : ret;
382 }
383
384 void nvme_ns_init_format(NvmeNamespace *ns);
385 int nvme_ns_setup(NvmeNamespace *ns, Error **errp);
386 void nvme_ns_drain(NvmeNamespace *ns);
387 void nvme_ns_shutdown(NvmeNamespace *ns);
388 void nvme_ns_cleanup(NvmeNamespace *ns);
389
390 typedef struct NvmeAsyncEvent {
391 QTAILQ_ENTRY(NvmeAsyncEvent) entry;
392 NvmeAerResult result;
393 } NvmeAsyncEvent;
394
395 enum {
396 NVME_SG_ALLOC = 1 << 0,
397 NVME_SG_DMA = 1 << 1,
398 };
399
400 typedef struct NvmeSg {
401 int flags;
402
403 union {
404 QEMUSGList qsg;
405 QEMUIOVector iov;
406 };
407 } NvmeSg;
408
409 typedef enum NvmeTxDirection {
410 NVME_TX_DIRECTION_TO_DEVICE = 0,
411 NVME_TX_DIRECTION_FROM_DEVICE = 1,
412 } NvmeTxDirection;
413
414 typedef struct NvmeRequest {
415 struct NvmeSQueue *sq;
416 struct NvmeNamespace *ns;
417 BlockAIOCB *aiocb;
418 uint16_t status;
419 void *opaque;
420 NvmeCqe cqe;
421 NvmeCmd cmd;
422 BlockAcctCookie acct;
423 NvmeSg sg;
424 QTAILQ_ENTRY(NvmeRequest)entry;
425 } NvmeRequest;
426
427 typedef struct NvmeBounceContext {
428 NvmeRequest *req;
429
430 struct {
431 QEMUIOVector iov;
432 uint8_t *bounce;
433 } data, mdata;
434 } NvmeBounceContext;
435
nvme_adm_opc_str(uint8_t opc)436 static inline const char *nvme_adm_opc_str(uint8_t opc)
437 {
438 switch (opc) {
439 case NVME_ADM_CMD_DELETE_SQ: return "NVME_ADM_CMD_DELETE_SQ";
440 case NVME_ADM_CMD_CREATE_SQ: return "NVME_ADM_CMD_CREATE_SQ";
441 case NVME_ADM_CMD_GET_LOG_PAGE: return "NVME_ADM_CMD_GET_LOG_PAGE";
442 case NVME_ADM_CMD_DELETE_CQ: return "NVME_ADM_CMD_DELETE_CQ";
443 case NVME_ADM_CMD_CREATE_CQ: return "NVME_ADM_CMD_CREATE_CQ";
444 case NVME_ADM_CMD_IDENTIFY: return "NVME_ADM_CMD_IDENTIFY";
445 case NVME_ADM_CMD_ABORT: return "NVME_ADM_CMD_ABORT";
446 case NVME_ADM_CMD_SET_FEATURES: return "NVME_ADM_CMD_SET_FEATURES";
447 case NVME_ADM_CMD_GET_FEATURES: return "NVME_ADM_CMD_GET_FEATURES";
448 case NVME_ADM_CMD_ASYNC_EV_REQ: return "NVME_ADM_CMD_ASYNC_EV_REQ";
449 case NVME_ADM_CMD_NS_ATTACHMENT: return "NVME_ADM_CMD_NS_ATTACHMENT";
450 case NVME_ADM_CMD_DIRECTIVE_SEND: return "NVME_ADM_CMD_DIRECTIVE_SEND";
451 case NVME_ADM_CMD_VIRT_MNGMT: return "NVME_ADM_CMD_VIRT_MNGMT";
452 case NVME_ADM_CMD_DIRECTIVE_RECV: return "NVME_ADM_CMD_DIRECTIVE_RECV";
453 case NVME_ADM_CMD_DBBUF_CONFIG: return "NVME_ADM_CMD_DBBUF_CONFIG";
454 case NVME_ADM_CMD_FORMAT_NVM: return "NVME_ADM_CMD_FORMAT_NVM";
455 default: return "NVME_ADM_CMD_UNKNOWN";
456 }
457 }
458
nvme_io_opc_str(uint8_t opc)459 static inline const char *nvme_io_opc_str(uint8_t opc)
460 {
461 switch (opc) {
462 case NVME_CMD_FLUSH: return "NVME_NVM_CMD_FLUSH";
463 case NVME_CMD_WRITE: return "NVME_NVM_CMD_WRITE";
464 case NVME_CMD_READ: return "NVME_NVM_CMD_READ";
465 case NVME_CMD_COMPARE: return "NVME_NVM_CMD_COMPARE";
466 case NVME_CMD_WRITE_ZEROES: return "NVME_NVM_CMD_WRITE_ZEROES";
467 case NVME_CMD_DSM: return "NVME_NVM_CMD_DSM";
468 case NVME_CMD_VERIFY: return "NVME_NVM_CMD_VERIFY";
469 case NVME_CMD_COPY: return "NVME_NVM_CMD_COPY";
470 case NVME_CMD_ZONE_MGMT_SEND: return "NVME_ZONED_CMD_MGMT_SEND";
471 case NVME_CMD_ZONE_MGMT_RECV: return "NVME_ZONED_CMD_MGMT_RECV";
472 case NVME_CMD_ZONE_APPEND: return "NVME_ZONED_CMD_ZONE_APPEND";
473 default: return "NVME_NVM_CMD_UNKNOWN";
474 }
475 }
476
477 typedef struct NvmeSQueue {
478 struct NvmeCtrl *ctrl;
479 uint16_t sqid;
480 uint16_t cqid;
481 uint32_t head;
482 uint32_t tail;
483 uint32_t size;
484 uint64_t dma_addr;
485 uint64_t db_addr;
486 uint64_t ei_addr;
487 QEMUBH *bh;
488 EventNotifier notifier;
489 bool ioeventfd_enabled;
490 NvmeRequest *io_req;
491 QTAILQ_HEAD(, NvmeRequest) req_list;
492 QTAILQ_HEAD(, NvmeRequest) out_req_list;
493 QTAILQ_ENTRY(NvmeSQueue) entry;
494 } NvmeSQueue;
495
496 typedef struct NvmeCQueue {
497 struct NvmeCtrl *ctrl;
498 uint8_t phase;
499 uint16_t cqid;
500 uint16_t irq_enabled;
501 uint32_t head;
502 uint32_t tail;
503 uint32_t vector;
504 uint32_t size;
505 uint64_t dma_addr;
506 uint64_t db_addr;
507 uint64_t ei_addr;
508 QEMUBH *bh;
509 EventNotifier notifier;
510 bool ioeventfd_enabled;
511 QTAILQ_HEAD(, NvmeSQueue) sq_list;
512 QTAILQ_HEAD(, NvmeRequest) req_list;
513 } NvmeCQueue;
514
515 #define TYPE_NVME "nvme"
516 #define NVME(obj) \
517 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
518
519 typedef struct NvmeParams {
520 char *serial;
521 uint32_t num_queues; /* deprecated since 5.1 */
522 uint32_t max_ioqpairs;
523 uint16_t msix_qsize;
524 uint16_t mqes;
525 uint32_t cmb_size_mb;
526 uint8_t aerl;
527 uint32_t aer_max_queued;
528 uint8_t mdts;
529 uint8_t vsl;
530 bool use_intel_id;
531 uint8_t zasl;
532 bool auto_transition_zones;
533 bool legacy_cmb;
534 bool ioeventfd;
535 uint16_t sriov_max_vfs;
536 uint16_t sriov_vq_flexible;
537 uint16_t sriov_vi_flexible;
538 uint32_t sriov_max_vq_per_vf;
539 uint32_t sriov_max_vi_per_vf;
540 bool msix_exclusive_bar;
541 } NvmeParams;
542
543 typedef struct NvmeCtrl {
544 PCIDevice parent_obj;
545 MemoryRegion bar0;
546 MemoryRegion iomem;
547 NvmeBar bar;
548 NvmeParams params;
549 NvmeBus bus;
550
551 uint16_t cntlid;
552 bool qs_created;
553 uint32_t page_size;
554 uint16_t page_bits;
555 uint16_t max_prp_ents;
556 uint32_t max_q_ents;
557 uint8_t outstanding_aers;
558 uint32_t irq_status;
559 int cq_pending;
560 uint64_t host_timestamp; /* Timestamp sent by the host */
561 uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
562 uint64_t starttime_ms;
563 uint16_t temperature;
564 uint8_t smart_critical_warning;
565 uint32_t conf_msix_qsize;
566 uint32_t conf_ioqpairs;
567 uint64_t dbbuf_dbs;
568 uint64_t dbbuf_eis;
569 bool dbbuf_enabled;
570
571 struct {
572 MemoryRegion mem;
573 uint8_t *buf;
574 bool cmse;
575 hwaddr cba;
576 } cmb;
577
578 struct {
579 HostMemoryBackend *dev;
580 bool cmse;
581 hwaddr cba;
582 } pmr;
583
584 uint8_t aer_mask;
585 NvmeRequest **aer_reqs;
586 QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
587 int aer_queued;
588
589 uint32_t dmrsl;
590
591 /* Namespace ID is started with 1 so bitmap should be 1-based */
592 #define NVME_CHANGED_NSID_SIZE (NVME_MAX_NAMESPACES + 1)
593 DECLARE_BITMAP(changed_nsids, NVME_CHANGED_NSID_SIZE);
594
595 NvmeSubsystem *subsys;
596
597 NvmeNamespace namespace;
598 NvmeNamespace *namespaces[NVME_MAX_NAMESPACES + 1];
599 NvmeSQueue **sq;
600 NvmeCQueue **cq;
601 NvmeSQueue admin_sq;
602 NvmeCQueue admin_cq;
603 NvmeIdCtrl id_ctrl;
604
605 struct {
606 struct {
607 uint16_t temp_thresh_hi;
608 uint16_t temp_thresh_low;
609 };
610
611 uint32_t async_config;
612 NvmeHostBehaviorSupport hbs;
613 } features;
614
615 NvmePriCtrlCap pri_ctrl_cap;
616 uint32_t nr_sec_ctrls;
617 NvmeSecCtrlEntry *sec_ctrl_list;
618 struct {
619 uint16_t vqrfap;
620 uint16_t virfap;
621 } next_pri_ctrl_cap; /* These override pri_ctrl_cap after reset */
622 } NvmeCtrl;
623
624 typedef enum NvmeResetType {
625 NVME_RESET_FUNCTION = 0,
626 NVME_RESET_CONTROLLER = 1,
627 } NvmeResetType;
628
nvme_ns(NvmeCtrl * n,uint32_t nsid)629 static inline NvmeNamespace *nvme_ns(NvmeCtrl *n, uint32_t nsid)
630 {
631 if (!nsid || nsid > NVME_MAX_NAMESPACES) {
632 return NULL;
633 }
634
635 return n->namespaces[nsid];
636 }
637
nvme_cq(NvmeRequest * req)638 static inline NvmeCQueue *nvme_cq(NvmeRequest *req)
639 {
640 NvmeSQueue *sq = req->sq;
641 NvmeCtrl *n = sq->ctrl;
642
643 return n->cq[sq->cqid];
644 }
645
nvme_ctrl(NvmeRequest * req)646 static inline NvmeCtrl *nvme_ctrl(NvmeRequest *req)
647 {
648 NvmeSQueue *sq = req->sq;
649 return sq->ctrl;
650 }
651
nvme_cid(NvmeRequest * req)652 static inline uint16_t nvme_cid(NvmeRequest *req)
653 {
654 if (!req) {
655 return 0xffff;
656 }
657
658 return le16_to_cpu(req->cqe.cid);
659 }
660
nvme_sctrl(NvmeCtrl * n)661 static inline NvmeSecCtrlEntry *nvme_sctrl(NvmeCtrl *n)
662 {
663 PCIDevice *pci_dev = &n->parent_obj;
664 NvmeCtrl *pf = NVME(pcie_sriov_get_pf(pci_dev));
665
666 if (pci_is_vf(pci_dev)) {
667 return &pf->sec_ctrl_list[pcie_sriov_vf_number(pci_dev)];
668 }
669
670 return NULL;
671 }
672
nvme_sctrl_for_cntlid(NvmeCtrl * n,uint16_t cntlid)673 static inline NvmeSecCtrlEntry *nvme_sctrl_for_cntlid(NvmeCtrl *n,
674 uint16_t cntlid)
675 {
676 NvmeSecCtrlEntry *list = n->sec_ctrl_list;
677 uint8_t i;
678
679 for (i = 0; i < n->nr_sec_ctrls; i++) {
680 if (le16_to_cpu(list[i].scid) == cntlid) {
681 return &list[i];
682 }
683 }
684
685 return NULL;
686 }
687
688 void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns);
689 uint16_t nvme_bounce_data(NvmeCtrl *n, void *ptr, uint32_t len,
690 NvmeTxDirection dir, NvmeRequest *req);
691 uint16_t nvme_bounce_mdata(NvmeCtrl *n, void *ptr, uint32_t len,
692 NvmeTxDirection dir, NvmeRequest *req);
693 void nvme_rw_complete_cb(void *opaque, int ret);
694 uint16_t nvme_map_dptr(NvmeCtrl *n, NvmeSg *sg, size_t len,
695 NvmeCmd *cmd);
696
697 #endif /* HW_NVME_NVME_H */
698