hw/isa/Kconfig: Add missing dependency VIA VT82C686 -> APM
[qemu/ar7.git] / hw / block / nvme.h
blob5d05ec368f7a993f71d3d9ed9809c2346605479a
1 #ifndef HW_NVME_H
2 #define HW_NVME_H
4 #include "block/nvme.h"
5 #include "hw/pci/pci.h"
6 #include "nvme-subsys.h"
7 #include "nvme-ns.h"
9 #define NVME_DEFAULT_ZONE_SIZE (128 * MiB)
10 #define NVME_DEFAULT_MAX_ZA_SIZE (128 * KiB)
12 typedef struct NvmeParams {
13 char *serial;
14 uint32_t num_queues; /* deprecated since 5.1 */
15 uint32_t max_ioqpairs;
16 uint16_t msix_qsize;
17 uint32_t cmb_size_mb;
18 uint8_t aerl;
19 uint32_t aer_max_queued;
20 uint8_t mdts;
21 uint8_t vsl;
22 bool use_intel_id;
23 uint8_t zasl;
24 bool legacy_cmb;
25 } NvmeParams;
27 typedef struct NvmeAsyncEvent {
28 QTAILQ_ENTRY(NvmeAsyncEvent) entry;
29 NvmeAerResult result;
30 } NvmeAsyncEvent;
32 enum {
33 NVME_SG_ALLOC = 1 << 0,
34 NVME_SG_DMA = 1 << 1,
37 typedef struct NvmeSg {
38 int flags;
40 union {
41 QEMUSGList qsg;
42 QEMUIOVector iov;
44 } NvmeSg;
46 typedef struct NvmeRequest {
47 struct NvmeSQueue *sq;
48 struct NvmeNamespace *ns;
49 BlockAIOCB *aiocb;
50 uint16_t status;
51 void *opaque;
52 NvmeCqe cqe;
53 NvmeCmd cmd;
54 BlockAcctCookie acct;
55 NvmeSg sg;
56 QTAILQ_ENTRY(NvmeRequest)entry;
57 } NvmeRequest;
59 typedef struct NvmeBounceContext {
60 NvmeRequest *req;
62 struct {
63 QEMUIOVector iov;
64 uint8_t *bounce;
65 } data, mdata;
66 } NvmeBounceContext;
68 static inline const char *nvme_adm_opc_str(uint8_t opc)
70 switch (opc) {
71 case NVME_ADM_CMD_DELETE_SQ: return "NVME_ADM_CMD_DELETE_SQ";
72 case NVME_ADM_CMD_CREATE_SQ: return "NVME_ADM_CMD_CREATE_SQ";
73 case NVME_ADM_CMD_GET_LOG_PAGE: return "NVME_ADM_CMD_GET_LOG_PAGE";
74 case NVME_ADM_CMD_DELETE_CQ: return "NVME_ADM_CMD_DELETE_CQ";
75 case NVME_ADM_CMD_CREATE_CQ: return "NVME_ADM_CMD_CREATE_CQ";
76 case NVME_ADM_CMD_IDENTIFY: return "NVME_ADM_CMD_IDENTIFY";
77 case NVME_ADM_CMD_ABORT: return "NVME_ADM_CMD_ABORT";
78 case NVME_ADM_CMD_SET_FEATURES: return "NVME_ADM_CMD_SET_FEATURES";
79 case NVME_ADM_CMD_GET_FEATURES: return "NVME_ADM_CMD_GET_FEATURES";
80 case NVME_ADM_CMD_ASYNC_EV_REQ: return "NVME_ADM_CMD_ASYNC_EV_REQ";
81 case NVME_ADM_CMD_NS_ATTACHMENT: return "NVME_ADM_CMD_NS_ATTACHMENT";
82 case NVME_ADM_CMD_FORMAT_NVM: return "NVME_ADM_CMD_FORMAT_NVM";
83 default: return "NVME_ADM_CMD_UNKNOWN";
87 static inline const char *nvme_io_opc_str(uint8_t opc)
89 switch (opc) {
90 case NVME_CMD_FLUSH: return "NVME_NVM_CMD_FLUSH";
91 case NVME_CMD_WRITE: return "NVME_NVM_CMD_WRITE";
92 case NVME_CMD_READ: return "NVME_NVM_CMD_READ";
93 case NVME_CMD_COMPARE: return "NVME_NVM_CMD_COMPARE";
94 case NVME_CMD_WRITE_ZEROES: return "NVME_NVM_CMD_WRITE_ZEROES";
95 case NVME_CMD_DSM: return "NVME_NVM_CMD_DSM";
96 case NVME_CMD_VERIFY: return "NVME_NVM_CMD_VERIFY";
97 case NVME_CMD_COPY: return "NVME_NVM_CMD_COPY";
98 case NVME_CMD_ZONE_MGMT_SEND: return "NVME_ZONED_CMD_MGMT_SEND";
99 case NVME_CMD_ZONE_MGMT_RECV: return "NVME_ZONED_CMD_MGMT_RECV";
100 case NVME_CMD_ZONE_APPEND: return "NVME_ZONED_CMD_ZONE_APPEND";
101 default: return "NVME_NVM_CMD_UNKNOWN";
105 typedef struct NvmeSQueue {
106 struct NvmeCtrl *ctrl;
107 uint16_t sqid;
108 uint16_t cqid;
109 uint32_t head;
110 uint32_t tail;
111 uint32_t size;
112 uint64_t dma_addr;
113 QEMUTimer *timer;
114 NvmeRequest *io_req;
115 QTAILQ_HEAD(, NvmeRequest) req_list;
116 QTAILQ_HEAD(, NvmeRequest) out_req_list;
117 QTAILQ_ENTRY(NvmeSQueue) entry;
118 } NvmeSQueue;
120 typedef struct NvmeCQueue {
121 struct NvmeCtrl *ctrl;
122 uint8_t phase;
123 uint16_t cqid;
124 uint16_t irq_enabled;
125 uint32_t head;
126 uint32_t tail;
127 uint32_t vector;
128 uint32_t size;
129 uint64_t dma_addr;
130 QEMUTimer *timer;
131 QTAILQ_HEAD(, NvmeSQueue) sq_list;
132 QTAILQ_HEAD(, NvmeRequest) req_list;
133 } NvmeCQueue;
135 #define TYPE_NVME_BUS "nvme-bus"
136 #define NVME_BUS(obj) OBJECT_CHECK(NvmeBus, (obj), TYPE_NVME_BUS)
138 typedef struct NvmeBus {
139 BusState parent_bus;
140 } NvmeBus;
142 #define TYPE_NVME "nvme"
143 #define NVME(obj) \
144 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
146 typedef struct NvmeFeatureVal {
147 struct {
148 uint16_t temp_thresh_hi;
149 uint16_t temp_thresh_low;
151 uint32_t async_config;
152 } NvmeFeatureVal;
154 typedef struct NvmeCtrl {
155 PCIDevice parent_obj;
156 MemoryRegion bar0;
157 MemoryRegion iomem;
158 NvmeBar bar;
159 NvmeParams params;
160 NvmeBus bus;
162 uint16_t cntlid;
163 bool qs_created;
164 uint32_t page_size;
165 uint16_t page_bits;
166 uint16_t max_prp_ents;
167 uint16_t cqe_size;
168 uint16_t sqe_size;
169 uint32_t reg_size;
170 uint32_t num_namespaces;
171 uint32_t max_q_ents;
172 uint8_t outstanding_aers;
173 uint32_t irq_status;
174 uint64_t host_timestamp; /* Timestamp sent by the host */
175 uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
176 uint64_t starttime_ms;
177 uint16_t temperature;
178 uint8_t smart_critical_warning;
180 struct {
181 MemoryRegion mem;
182 uint8_t *buf;
183 bool cmse;
184 hwaddr cba;
185 } cmb;
187 struct {
188 HostMemoryBackend *dev;
189 bool cmse;
190 hwaddr cba;
191 } pmr;
193 uint8_t aer_mask;
194 NvmeRequest **aer_reqs;
195 QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
196 int aer_queued;
198 uint32_t dmrsl;
200 /* Namespace ID is started with 1 so bitmap should be 1-based */
201 #define NVME_CHANGED_NSID_SIZE (NVME_MAX_NAMESPACES + 1)
202 DECLARE_BITMAP(changed_nsids, NVME_CHANGED_NSID_SIZE);
204 NvmeSubsystem *subsys;
206 NvmeNamespace namespace;
208 * Attached namespaces to this controller. If subsys is not given, all
209 * namespaces in this list will always be attached.
211 NvmeNamespace *namespaces[NVME_MAX_NAMESPACES];
212 NvmeSQueue **sq;
213 NvmeCQueue **cq;
214 NvmeSQueue admin_sq;
215 NvmeCQueue admin_cq;
216 NvmeIdCtrl id_ctrl;
217 NvmeFeatureVal features;
218 } NvmeCtrl;
220 static inline NvmeNamespace *nvme_ns(NvmeCtrl *n, uint32_t nsid)
222 if (!nsid || nsid > n->num_namespaces) {
223 return NULL;
226 return n->namespaces[nsid - 1];
229 static inline NvmeCQueue *nvme_cq(NvmeRequest *req)
231 NvmeSQueue *sq = req->sq;
232 NvmeCtrl *n = sq->ctrl;
234 return n->cq[sq->cqid];
237 static inline NvmeCtrl *nvme_ctrl(NvmeRequest *req)
239 NvmeSQueue *sq = req->sq;
240 return sq->ctrl;
243 static inline uint16_t nvme_cid(NvmeRequest *req)
245 if (!req) {
246 return 0xffff;
249 return le16_to_cpu(req->cqe.cid);
252 typedef enum NvmeTxDirection {
253 NVME_TX_DIRECTION_TO_DEVICE = 0,
254 NVME_TX_DIRECTION_FROM_DEVICE = 1,
255 } NvmeTxDirection;
257 void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns);
258 uint16_t nvme_bounce_data(NvmeCtrl *n, uint8_t *ptr, uint32_t len,
259 NvmeTxDirection dir, NvmeRequest *req);
260 uint16_t nvme_bounce_mdata(NvmeCtrl *n, uint8_t *ptr, uint32_t len,
261 NvmeTxDirection dir, NvmeRequest *req);
262 void nvme_rw_complete_cb(void *opaque, int ret);
263 uint16_t nvme_map_dptr(NvmeCtrl *n, NvmeSg *sg, size_t len,
264 NvmeCmd *cmd);
266 #endif /* HW_NVME_H */