Merge remote-tracking branch 'remotes/philmd-gitlab/tags/renesas-20201027' into staging
[qemu.git] / hw / block / nvme.h
1 #ifndef HW_NVME_H
2 #define HW_NVME_H
3
4 #include "block/nvme.h"
5
6 typedef struct NvmeParams {
7 char *serial;
8 uint32_t num_queues; /* deprecated since 5.1 */
9 uint32_t max_ioqpairs;
10 uint16_t msix_qsize;
11 uint32_t cmb_size_mb;
12 uint8_t aerl;
13 uint32_t aer_max_queued;
14 uint8_t mdts;
15 } NvmeParams;
16
17 typedef struct NvmeAsyncEvent {
18 QTAILQ_ENTRY(NvmeAsyncEvent) entry;
19 NvmeAerResult result;
20 } NvmeAsyncEvent;
21
22 typedef struct NvmeRequest {
23 struct NvmeSQueue *sq;
24 struct NvmeNamespace *ns;
25 BlockAIOCB *aiocb;
26 uint16_t status;
27 NvmeCqe cqe;
28 NvmeCmd cmd;
29 BlockAcctCookie acct;
30 QEMUSGList qsg;
31 QEMUIOVector iov;
32 QTAILQ_ENTRY(NvmeRequest)entry;
33 } NvmeRequest;
34
35 typedef struct NvmeSQueue {
36 struct NvmeCtrl *ctrl;
37 uint16_t sqid;
38 uint16_t cqid;
39 uint32_t head;
40 uint32_t tail;
41 uint32_t size;
42 uint64_t dma_addr;
43 QEMUTimer *timer;
44 NvmeRequest *io_req;
45 QTAILQ_HEAD(, NvmeRequest) req_list;
46 QTAILQ_HEAD(, NvmeRequest) out_req_list;
47 QTAILQ_ENTRY(NvmeSQueue) entry;
48 } NvmeSQueue;
49
50 typedef struct NvmeCQueue {
51 struct NvmeCtrl *ctrl;
52 uint8_t phase;
53 uint16_t cqid;
54 uint16_t irq_enabled;
55 uint32_t head;
56 uint32_t tail;
57 uint32_t vector;
58 uint32_t size;
59 uint64_t dma_addr;
60 QEMUTimer *timer;
61 QTAILQ_HEAD(, NvmeSQueue) sq_list;
62 QTAILQ_HEAD(, NvmeRequest) req_list;
63 } NvmeCQueue;
64
65 typedef struct NvmeNamespace {
66 NvmeIdNs id_ns;
67 } NvmeNamespace;
68
69 static inline NvmeLBAF *nvme_ns_lbaf(NvmeNamespace *ns)
70 {
71 NvmeIdNs *id_ns = &ns->id_ns;
72 return &id_ns->lbaf[NVME_ID_NS_FLBAS_INDEX(id_ns->flbas)];
73 }
74
75 static inline uint8_t nvme_ns_lbads(NvmeNamespace *ns)
76 {
77 return nvme_ns_lbaf(ns)->ds;
78 }
79
80 #define TYPE_NVME "nvme"
81 #define NVME(obj) \
82 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
83
84 typedef struct NvmeFeatureVal {
85 struct {
86 uint16_t temp_thresh_hi;
87 uint16_t temp_thresh_low;
88 };
89 uint32_t async_config;
90 } NvmeFeatureVal;
91
92 typedef struct NvmeCtrl {
93 PCIDevice parent_obj;
94 MemoryRegion iomem;
95 MemoryRegion ctrl_mem;
96 NvmeBar bar;
97 BlockConf conf;
98 NvmeParams params;
99
100 bool qs_created;
101 uint32_t page_size;
102 uint16_t page_bits;
103 uint16_t max_prp_ents;
104 uint16_t cqe_size;
105 uint16_t sqe_size;
106 uint32_t reg_size;
107 uint32_t num_namespaces;
108 uint32_t max_q_ents;
109 uint64_t ns_size;
110 uint8_t outstanding_aers;
111 uint8_t *cmbuf;
112 uint32_t irq_status;
113 uint64_t host_timestamp; /* Timestamp sent by the host */
114 uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
115 uint64_t starttime_ms;
116 uint16_t temperature;
117
118 HostMemoryBackend *pmrdev;
119
120 uint8_t aer_mask;
121 NvmeRequest **aer_reqs;
122 QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
123 int aer_queued;
124
125 NvmeNamespace *namespaces;
126 NvmeSQueue **sq;
127 NvmeCQueue **cq;
128 NvmeSQueue admin_sq;
129 NvmeCQueue admin_cq;
130 NvmeIdCtrl id_ctrl;
131 NvmeFeatureVal features;
132 } NvmeCtrl;
133
134 /* calculate the number of LBAs that the namespace can accomodate */
135 static inline uint64_t nvme_ns_nlbas(NvmeCtrl *n, NvmeNamespace *ns)
136 {
137 return n->ns_size >> nvme_ns_lbads(ns);
138 }
139
140 #endif /* HW_NVME_H */