1#ifndef HW_NVME_H 2#define HW_NVME_H 3#include "qemu/cutils.h" 4#include "block/nvme.h" 5 6typedef struct NvmeAsyncEvent { 7 QSIMPLEQ_ENTRY(NvmeAsyncEvent) entry; 8 NvmeAerResult result; 9} NvmeAsyncEvent; 10 11typedef struct NvmeRequest { 12 struct NvmeSQueue *sq; 13 BlockAIOCB *aiocb; 14 uint16_t status; 15 bool has_sg; 16 NvmeCqe cqe; 17 BlockAcctCookie acct; 18 QEMUSGList qsg; 19 QEMUIOVector iov; 20 QTAILQ_ENTRY(NvmeRequest)entry; 21} NvmeRequest; 22 23typedef struct NvmeSQueue { 24 struct NvmeCtrl *ctrl; 25 uint16_t sqid; 26 uint16_t cqid; 27 uint32_t head; 28 uint32_t tail; 29 uint32_t size; 30 uint64_t dma_addr; 31 QEMUTimer *timer; 32 NvmeRequest *io_req; 33 QTAILQ_HEAD(sq_req_list, NvmeRequest) req_list; 34 QTAILQ_HEAD(out_req_list, NvmeRequest) out_req_list; 35 QTAILQ_ENTRY(NvmeSQueue) entry; 36} NvmeSQueue; 37 38typedef struct NvmeCQueue { 39 struct NvmeCtrl *ctrl; 40 uint8_t phase; 41 uint16_t cqid; 42 uint16_t irq_enabled; 43 uint32_t head; 44 uint32_t tail; 45 uint32_t vector; 46 uint32_t size; 47 uint64_t dma_addr; 48 QEMUTimer *timer; 49 QTAILQ_HEAD(sq_list, NvmeSQueue) sq_list; 50 QTAILQ_HEAD(cq_req_list, NvmeRequest) req_list; 51} NvmeCQueue; 52 53typedef struct NvmeNamespace { 54 NvmeIdNs id_ns; 55} NvmeNamespace; 56 57#define TYPE_NVME "nvme" 58#define NVME(obj) \ 59 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME) 60 61typedef struct NvmeCtrl { 62 PCIDevice parent_obj; 63 MemoryRegion iomem; 64 MemoryRegion ctrl_mem; 65 NvmeBar bar; 66 BlockConf conf; 67 68 uint32_t page_size; 69 uint16_t page_bits; 70 uint16_t max_prp_ents; 71 uint16_t cqe_size; 72 uint16_t sqe_size; 73 uint32_t reg_size; 74 uint32_t num_namespaces; 75 uint32_t num_queues; 76 uint32_t max_q_ents; 77 uint64_t ns_size; 78 uint32_t cmb_size_mb; 79 uint32_t cmbsz; 80 uint32_t cmbloc; 81 uint8_t *cmbuf; 82 uint64_t irq_status; 83 84 char *serial; 85 NvmeNamespace *namespaces; 86 NvmeSQueue **sq; 87 NvmeCQueue **cq; 88 NvmeSQueue admin_sq; 89 NvmeCQueue admin_cq; 90 NvmeIdCtrl id_ctrl; 91} NvmeCtrl; 92 93#endif /* HW_NVME_H */ 94