target/mips: Remove XBurst Media eXtension Unit dead code
[qemu/ar7.git] / hw / block / nvme.h
blob4955d649c7d49329f1812b77e9aa5f6a90da96fb
1 #ifndef HW_NVME_H
2 #define HW_NVME_H
4 #include "block/nvme.h"
5 #include "nvme-subsys.h"
6 #include "nvme-ns.h"
8 #define NVME_MAX_NAMESPACES 256
10 #define NVME_DEFAULT_ZONE_SIZE (128 * MiB)
11 #define NVME_DEFAULT_MAX_ZA_SIZE (128 * KiB)
14 * Subsystem namespace list for allocated namespaces should be larger than
15 * attached namespace list in a controller.
17 QEMU_BUILD_BUG_ON(NVME_MAX_NAMESPACES > NVME_SUBSYS_MAX_NAMESPACES);
19 typedef struct NvmeParams {
20 char *serial;
21 uint32_t num_queues; /* deprecated since 5.1 */
22 uint32_t max_ioqpairs;
23 uint16_t msix_qsize;
24 uint32_t cmb_size_mb;
25 uint8_t aerl;
26 uint32_t aer_max_queued;
27 uint8_t mdts;
28 bool use_intel_id;
29 uint8_t zasl;
30 bool legacy_cmb;
31 } NvmeParams;
33 typedef struct NvmeAsyncEvent {
34 QTAILQ_ENTRY(NvmeAsyncEvent) entry;
35 NvmeAerResult result;
36 } NvmeAsyncEvent;
38 enum {
39 NVME_SG_ALLOC = 1 << 0,
40 NVME_SG_DMA = 1 << 1,
43 typedef struct NvmeSg {
44 int flags;
46 union {
47 QEMUSGList qsg;
48 QEMUIOVector iov;
50 } NvmeSg;
52 typedef struct NvmeRequest {
53 struct NvmeSQueue *sq;
54 struct NvmeNamespace *ns;
55 BlockAIOCB *aiocb;
56 uint16_t status;
57 void *opaque;
58 NvmeCqe cqe;
59 NvmeCmd cmd;
60 BlockAcctCookie acct;
61 NvmeSg sg;
62 QTAILQ_ENTRY(NvmeRequest)entry;
63 } NvmeRequest;
65 static inline const char *nvme_adm_opc_str(uint8_t opc)
67 switch (opc) {
68 case NVME_ADM_CMD_DELETE_SQ: return "NVME_ADM_CMD_DELETE_SQ";
69 case NVME_ADM_CMD_CREATE_SQ: return "NVME_ADM_CMD_CREATE_SQ";
70 case NVME_ADM_CMD_GET_LOG_PAGE: return "NVME_ADM_CMD_GET_LOG_PAGE";
71 case NVME_ADM_CMD_DELETE_CQ: return "NVME_ADM_CMD_DELETE_CQ";
72 case NVME_ADM_CMD_CREATE_CQ: return "NVME_ADM_CMD_CREATE_CQ";
73 case NVME_ADM_CMD_IDENTIFY: return "NVME_ADM_CMD_IDENTIFY";
74 case NVME_ADM_CMD_ABORT: return "NVME_ADM_CMD_ABORT";
75 case NVME_ADM_CMD_SET_FEATURES: return "NVME_ADM_CMD_SET_FEATURES";
76 case NVME_ADM_CMD_GET_FEATURES: return "NVME_ADM_CMD_GET_FEATURES";
77 case NVME_ADM_CMD_ASYNC_EV_REQ: return "NVME_ADM_CMD_ASYNC_EV_REQ";
78 default: return "NVME_ADM_CMD_UNKNOWN";
82 static inline const char *nvme_io_opc_str(uint8_t opc)
84 switch (opc) {
85 case NVME_CMD_FLUSH: return "NVME_NVM_CMD_FLUSH";
86 case NVME_CMD_WRITE: return "NVME_NVM_CMD_WRITE";
87 case NVME_CMD_READ: return "NVME_NVM_CMD_READ";
88 case NVME_CMD_COMPARE: return "NVME_NVM_CMD_COMPARE";
89 case NVME_CMD_WRITE_ZEROES: return "NVME_NVM_CMD_WRITE_ZEROES";
90 case NVME_CMD_DSM: return "NVME_NVM_CMD_DSM";
91 case NVME_CMD_COPY: return "NVME_NVM_CMD_COPY";
92 case NVME_CMD_ZONE_MGMT_SEND: return "NVME_ZONED_CMD_MGMT_SEND";
93 case NVME_CMD_ZONE_MGMT_RECV: return "NVME_ZONED_CMD_MGMT_RECV";
94 case NVME_CMD_ZONE_APPEND: return "NVME_ZONED_CMD_ZONE_APPEND";
95 default: return "NVME_NVM_CMD_UNKNOWN";
99 typedef struct NvmeSQueue {
100 struct NvmeCtrl *ctrl;
101 uint16_t sqid;
102 uint16_t cqid;
103 uint32_t head;
104 uint32_t tail;
105 uint32_t size;
106 uint64_t dma_addr;
107 QEMUTimer *timer;
108 NvmeRequest *io_req;
109 QTAILQ_HEAD(, NvmeRequest) req_list;
110 QTAILQ_HEAD(, NvmeRequest) out_req_list;
111 QTAILQ_ENTRY(NvmeSQueue) entry;
112 } NvmeSQueue;
114 typedef struct NvmeCQueue {
115 struct NvmeCtrl *ctrl;
116 uint8_t phase;
117 uint16_t cqid;
118 uint16_t irq_enabled;
119 uint32_t head;
120 uint32_t tail;
121 uint32_t vector;
122 uint32_t size;
123 uint64_t dma_addr;
124 QEMUTimer *timer;
125 QTAILQ_HEAD(, NvmeSQueue) sq_list;
126 QTAILQ_HEAD(, NvmeRequest) req_list;
127 } NvmeCQueue;
129 #define TYPE_NVME_BUS "nvme-bus"
130 #define NVME_BUS(obj) OBJECT_CHECK(NvmeBus, (obj), TYPE_NVME_BUS)
132 typedef struct NvmeBus {
133 BusState parent_bus;
134 } NvmeBus;
136 #define TYPE_NVME "nvme"
137 #define NVME(obj) \
138 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
140 typedef struct NvmeFeatureVal {
141 struct {
142 uint16_t temp_thresh_hi;
143 uint16_t temp_thresh_low;
145 uint32_t async_config;
146 } NvmeFeatureVal;
148 typedef struct NvmeCtrl {
149 PCIDevice parent_obj;
150 MemoryRegion bar0;
151 MemoryRegion iomem;
152 NvmeBar bar;
153 NvmeParams params;
154 NvmeBus bus;
155 BlockConf conf;
157 uint16_t cntlid;
158 bool qs_created;
159 uint32_t page_size;
160 uint16_t page_bits;
161 uint16_t max_prp_ents;
162 uint16_t cqe_size;
163 uint16_t sqe_size;
164 uint32_t reg_size;
165 uint32_t num_namespaces;
166 uint32_t max_q_ents;
167 uint8_t outstanding_aers;
168 uint32_t irq_status;
169 uint64_t host_timestamp; /* Timestamp sent by the host */
170 uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
171 uint64_t starttime_ms;
172 uint16_t temperature;
173 uint8_t smart_critical_warning;
175 struct {
176 MemoryRegion mem;
177 uint8_t *buf;
178 bool cmse;
179 hwaddr cba;
180 } cmb;
182 struct {
183 HostMemoryBackend *dev;
184 bool cmse;
185 hwaddr cba;
186 } pmr;
188 uint8_t aer_mask;
189 NvmeRequest **aer_reqs;
190 QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
191 int aer_queued;
193 uint32_t dmrsl;
195 /* Namespace ID is started with 1 so bitmap should be 1-based */
196 #define NVME_CHANGED_NSID_SIZE (NVME_MAX_NAMESPACES + 1)
197 DECLARE_BITMAP(changed_nsids, NVME_CHANGED_NSID_SIZE);
199 NvmeSubsystem *subsys;
201 NvmeNamespace namespace;
203 * Attached namespaces to this controller. If subsys is not given, all
204 * namespaces in this list will always be attached.
206 NvmeNamespace *namespaces[NVME_MAX_NAMESPACES];
207 NvmeSQueue **sq;
208 NvmeCQueue **cq;
209 NvmeSQueue admin_sq;
210 NvmeCQueue admin_cq;
211 NvmeIdCtrl id_ctrl;
212 NvmeFeatureVal features;
213 } NvmeCtrl;
215 static inline NvmeNamespace *nvme_ns(NvmeCtrl *n, uint32_t nsid)
217 if (!nsid || nsid > n->num_namespaces) {
218 return NULL;
221 return n->namespaces[nsid - 1];
224 static inline bool nvme_ns_is_attached(NvmeCtrl *n, NvmeNamespace *ns)
226 int nsid;
228 for (nsid = 1; nsid <= n->num_namespaces; nsid++) {
229 if (nvme_ns(n, nsid) == ns) {
230 return true;
234 return false;
237 static inline void nvme_ns_attach(NvmeCtrl *n, NvmeNamespace *ns)
239 n->namespaces[nvme_nsid(ns) - 1] = ns;
242 static inline void nvme_ns_detach(NvmeCtrl *n, NvmeNamespace *ns)
244 n->namespaces[nvme_nsid(ns) - 1] = NULL;
247 static inline NvmeCQueue *nvme_cq(NvmeRequest *req)
249 NvmeSQueue *sq = req->sq;
250 NvmeCtrl *n = sq->ctrl;
252 return n->cq[sq->cqid];
255 static inline NvmeCtrl *nvme_ctrl(NvmeRequest *req)
257 NvmeSQueue *sq = req->sq;
258 return sq->ctrl;
261 int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp);
263 #endif /* HW_NVME_H */