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