| #ifndef HW_NVME_H |
| #define HW_NVME_H |
| |
| #include "block/nvme.h" |
| |
| typedef struct NvmeParams { |
| char *serial; |
| uint32_t num_queues; /* deprecated since 5.1 */ |
| uint32_t max_ioqpairs; |
| uint16_t msix_qsize; |
| uint32_t cmb_size_mb; |
| uint8_t aerl; |
| uint32_t aer_max_queued; |
| uint8_t mdts; |
| } NvmeParams; |
| |
| typedef struct NvmeAsyncEvent { |
| QTAILQ_ENTRY(NvmeAsyncEvent) entry; |
| NvmeAerResult result; |
| } NvmeAsyncEvent; |
| |
| typedef struct NvmeRequest { |
| struct NvmeSQueue *sq; |
| struct NvmeNamespace *ns; |
| BlockAIOCB *aiocb; |
| uint16_t status; |
| NvmeCqe cqe; |
| NvmeCmd cmd; |
| BlockAcctCookie acct; |
| QEMUSGList qsg; |
| QEMUIOVector iov; |
| QTAILQ_ENTRY(NvmeRequest)entry; |
| } NvmeRequest; |
| |
| typedef struct NvmeSQueue { |
| struct NvmeCtrl *ctrl; |
| uint16_t sqid; |
| uint16_t cqid; |
| uint32_t head; |
| uint32_t tail; |
| uint32_t size; |
| uint64_t dma_addr; |
| QEMUTimer *timer; |
| NvmeRequest *io_req; |
| QTAILQ_HEAD(, NvmeRequest) req_list; |
| QTAILQ_HEAD(, NvmeRequest) out_req_list; |
| QTAILQ_ENTRY(NvmeSQueue) entry; |
| } NvmeSQueue; |
| |
| typedef struct NvmeCQueue { |
| struct NvmeCtrl *ctrl; |
| uint8_t phase; |
| uint16_t cqid; |
| uint16_t irq_enabled; |
| uint32_t head; |
| uint32_t tail; |
| uint32_t vector; |
| uint32_t size; |
| uint64_t dma_addr; |
| QEMUTimer *timer; |
| QTAILQ_HEAD(, NvmeSQueue) sq_list; |
| QTAILQ_HEAD(, NvmeRequest) req_list; |
| } NvmeCQueue; |
| |
| typedef struct NvmeNamespace { |
| NvmeIdNs id_ns; |
| } NvmeNamespace; |
| |
| static inline NvmeLBAF *nvme_ns_lbaf(NvmeNamespace *ns) |
| { |
| NvmeIdNs *id_ns = &ns->id_ns; |
| return &id_ns->lbaf[NVME_ID_NS_FLBAS_INDEX(id_ns->flbas)]; |
| } |
| |
| static inline uint8_t nvme_ns_lbads(NvmeNamespace *ns) |
| { |
| return nvme_ns_lbaf(ns)->ds; |
| } |
| |
| #define TYPE_NVME "nvme" |
| #define NVME(obj) \ |
| OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME) |
| |
| typedef struct NvmeFeatureVal { |
| struct { |
| uint16_t temp_thresh_hi; |
| uint16_t temp_thresh_low; |
| }; |
| uint32_t async_config; |
| } NvmeFeatureVal; |
| |
| typedef struct NvmeCtrl { |
| PCIDevice parent_obj; |
| MemoryRegion iomem; |
| MemoryRegion ctrl_mem; |
| NvmeBar bar; |
| BlockConf conf; |
| NvmeParams params; |
| |
| bool qs_created; |
| uint32_t page_size; |
| uint16_t page_bits; |
| uint16_t max_prp_ents; |
| uint16_t cqe_size; |
| uint16_t sqe_size; |
| uint32_t reg_size; |
| uint32_t num_namespaces; |
| uint32_t max_q_ents; |
| uint64_t ns_size; |
| uint8_t outstanding_aers; |
| uint8_t *cmbuf; |
| uint32_t irq_status; |
| uint64_t host_timestamp; /* Timestamp sent by the host */ |
| uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */ |
| uint64_t starttime_ms; |
| uint16_t temperature; |
| |
| HostMemoryBackend *pmrdev; |
| |
| uint8_t aer_mask; |
| NvmeRequest **aer_reqs; |
| QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue; |
| int aer_queued; |
| |
| NvmeNamespace *namespaces; |
| NvmeSQueue **sq; |
| NvmeCQueue **cq; |
| NvmeSQueue admin_sq; |
| NvmeCQueue admin_cq; |
| NvmeIdCtrl id_ctrl; |
| NvmeFeatureVal features; |
| } NvmeCtrl; |
| |
| /* calculate the number of LBAs that the namespace can accomodate */ |
| static inline uint64_t nvme_ns_nlbas(NvmeCtrl *n, NvmeNamespace *ns) |
| { |
| return n->ns_size >> nvme_ns_lbads(ns); |
| } |
| |
| #endif /* HW_NVME_H */ |