blob: 557194ee1954008cabd85391624d99cfae7d26e4 [file] [log] [blame]
#ifndef HW_NVME_H
#define HW_NVME_H
#include "block/nvme.h"
typedef struct NvmeAsyncEvent {
QSIMPLEQ_ENTRY(NvmeAsyncEvent) entry;
NvmeAerResult result;
} NvmeAsyncEvent;
typedef struct NvmeRequest {
struct NvmeSQueue *sq;
BlockAIOCB *aiocb;
uint16_t status;
bool has_sg;
NvmeCqe cqe;
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;
#define TYPE_NVME "nvme"
#define NVME(obj) \
OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
typedef struct NvmeCtrl {
PCIDevice parent_obj;
MemoryRegion iomem;
MemoryRegion ctrl_mem;
NvmeBar bar;
BlockConf conf;
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 num_queues;
uint32_t max_q_ents;
uint64_t ns_size;
uint32_t cmb_size_mb;
uint32_t cmbsz;
uint32_t cmbloc;
uint8_t *cmbuf;
uint64_t irq_status;
uint64_t host_timestamp; /* Timestamp sent by the host */
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
char *serial;
NvmeNamespace *namespaces;
NvmeSQueue **sq;
NvmeCQueue **cq;
NvmeSQueue admin_sq;
NvmeCQueue admin_cq;
NvmeIdCtrl id_ctrl;
} NvmeCtrl;
#endif /* HW_NVME_H */