qemu/hw/block/nvme.h
<<
>>
Prefs
   1#ifndef HW_NVME_H
   2#define HW_NVME_H
   3
   4#include "block/nvme.h"
   5#include "nvme-ns.h"
   6
   7#define NVME_MAX_NAMESPACES 256
   8
   9typedef struct NvmeParams {
  10    char     *serial;
  11    uint32_t num_queues; /* deprecated since 5.1 */
  12    uint32_t max_ioqpairs;
  13    uint16_t msix_qsize;
  14    uint32_t cmb_size_mb;
  15    uint8_t  aerl;
  16    uint32_t aer_max_queued;
  17    uint8_t  mdts;
  18    bool     use_intel_id;
  19} NvmeParams;
  20
  21typedef struct NvmeAsyncEvent {
  22    QTAILQ_ENTRY(NvmeAsyncEvent) entry;
  23    NvmeAerResult result;
  24} NvmeAsyncEvent;
  25
  26typedef struct NvmeRequest {
  27    struct NvmeSQueue       *sq;
  28    struct NvmeNamespace    *ns;
  29    BlockAIOCB              *aiocb;
  30    uint16_t                status;
  31    NvmeCqe                 cqe;
  32    NvmeCmd                 cmd;
  33    BlockAcctCookie         acct;
  34    QEMUSGList              qsg;
  35    QEMUIOVector            iov;
  36    QTAILQ_ENTRY(NvmeRequest)entry;
  37} NvmeRequest;
  38
  39static inline const char *nvme_adm_opc_str(uint8_t opc)
  40{
  41    switch (opc) {
  42    case NVME_ADM_CMD_DELETE_SQ:        return "NVME_ADM_CMD_DELETE_SQ";
  43    case NVME_ADM_CMD_CREATE_SQ:        return "NVME_ADM_CMD_CREATE_SQ";
  44    case NVME_ADM_CMD_GET_LOG_PAGE:     return "NVME_ADM_CMD_GET_LOG_PAGE";
  45    case NVME_ADM_CMD_DELETE_CQ:        return "NVME_ADM_CMD_DELETE_CQ";
  46    case NVME_ADM_CMD_CREATE_CQ:        return "NVME_ADM_CMD_CREATE_CQ";
  47    case NVME_ADM_CMD_IDENTIFY:         return "NVME_ADM_CMD_IDENTIFY";
  48    case NVME_ADM_CMD_ABORT:            return "NVME_ADM_CMD_ABORT";
  49    case NVME_ADM_CMD_SET_FEATURES:     return "NVME_ADM_CMD_SET_FEATURES";
  50    case NVME_ADM_CMD_GET_FEATURES:     return "NVME_ADM_CMD_GET_FEATURES";
  51    case NVME_ADM_CMD_ASYNC_EV_REQ:     return "NVME_ADM_CMD_ASYNC_EV_REQ";
  52    default:                            return "NVME_ADM_CMD_UNKNOWN";
  53    }
  54}
  55
  56static inline const char *nvme_io_opc_str(uint8_t opc)
  57{
  58    switch (opc) {
  59    case NVME_CMD_FLUSH:            return "NVME_NVM_CMD_FLUSH";
  60    case NVME_CMD_WRITE:            return "NVME_NVM_CMD_WRITE";
  61    case NVME_CMD_READ:             return "NVME_NVM_CMD_READ";
  62    case NVME_CMD_WRITE_ZEROES:     return "NVME_NVM_CMD_WRITE_ZEROES";
  63    default:                        return "NVME_NVM_CMD_UNKNOWN";
  64    }
  65}
  66
  67typedef struct NvmeSQueue {
  68    struct NvmeCtrl *ctrl;
  69    uint16_t    sqid;
  70    uint16_t    cqid;
  71    uint32_t    head;
  72    uint32_t    tail;
  73    uint32_t    size;
  74    uint64_t    dma_addr;
  75    QEMUTimer   *timer;
  76    NvmeRequest *io_req;
  77    QTAILQ_HEAD(, NvmeRequest) req_list;
  78    QTAILQ_HEAD(, NvmeRequest) out_req_list;
  79    QTAILQ_ENTRY(NvmeSQueue) entry;
  80} NvmeSQueue;
  81
  82typedef struct NvmeCQueue {
  83    struct NvmeCtrl *ctrl;
  84    uint8_t     phase;
  85    uint16_t    cqid;
  86    uint16_t    irq_enabled;
  87    uint32_t    head;
  88    uint32_t    tail;
  89    uint32_t    vector;
  90    uint32_t    size;
  91    uint64_t    dma_addr;
  92    QEMUTimer   *timer;
  93    QTAILQ_HEAD(, NvmeSQueue) sq_list;
  94    QTAILQ_HEAD(, NvmeRequest) req_list;
  95} NvmeCQueue;
  96
  97#define TYPE_NVME_BUS "nvme-bus"
  98#define NVME_BUS(obj) OBJECT_CHECK(NvmeBus, (obj), TYPE_NVME_BUS)
  99
 100typedef struct NvmeBus {
 101    BusState parent_bus;
 102} NvmeBus;
 103
 104#define TYPE_NVME "nvme"
 105#define NVME(obj) \
 106        OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
 107
 108typedef struct NvmeFeatureVal {
 109    struct {
 110        uint16_t temp_thresh_hi;
 111        uint16_t temp_thresh_low;
 112    };
 113    uint32_t    async_config;
 114    uint32_t    vwc;
 115} NvmeFeatureVal;
 116
 117typedef struct NvmeCtrl {
 118    PCIDevice    parent_obj;
 119    MemoryRegion iomem;
 120    MemoryRegion ctrl_mem;
 121    NvmeBar      bar;
 122    NvmeParams   params;
 123    NvmeBus      bus;
 124    BlockConf    conf;
 125
 126    bool        qs_created;
 127    uint32_t    page_size;
 128    uint16_t    page_bits;
 129    uint16_t    max_prp_ents;
 130    uint16_t    cqe_size;
 131    uint16_t    sqe_size;
 132    uint32_t    reg_size;
 133    uint32_t    num_namespaces;
 134    uint32_t    max_q_ents;
 135    uint8_t     outstanding_aers;
 136    uint8_t     *cmbuf;
 137    uint32_t    irq_status;
 138    uint64_t    host_timestamp;                 /* Timestamp sent by the host */
 139    uint64_t    timestamp_set_qemu_clock_ms;    /* QEMU clock time */
 140    uint64_t    starttime_ms;
 141    uint16_t    temperature;
 142
 143    HostMemoryBackend *pmrdev;
 144
 145    uint8_t     aer_mask;
 146    NvmeRequest **aer_reqs;
 147    QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
 148    int         aer_queued;
 149
 150    NvmeNamespace   namespace;
 151    NvmeNamespace   *namespaces[NVME_MAX_NAMESPACES];
 152    NvmeSQueue      **sq;
 153    NvmeCQueue      **cq;
 154    NvmeSQueue      admin_sq;
 155    NvmeCQueue      admin_cq;
 156    NvmeIdCtrl      id_ctrl;
 157    NvmeFeatureVal  features;
 158} NvmeCtrl;
 159
 160static inline NvmeNamespace *nvme_ns(NvmeCtrl *n, uint32_t nsid)
 161{
 162    if (!nsid || nsid > n->num_namespaces) {
 163        return NULL;
 164    }
 165
 166    return n->namespaces[nsid - 1];
 167}
 168
 169static inline NvmeCQueue *nvme_cq(NvmeRequest *req)
 170{
 171    NvmeSQueue *sq = req->sq;
 172    NvmeCtrl *n = sq->ctrl;
 173
 174    return n->cq[sq->cqid];
 175}
 176
 177static inline NvmeCtrl *nvme_ctrl(NvmeRequest *req)
 178{
 179    NvmeSQueue *sq = req->sq;
 180    return sq->ctrl;
 181}
 182
 183int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp);
 184
 185#endif /* HW_NVME_H */
 186