4 #include "block/nvme.h"
5 #include "hw/pci/pci.h"
6 #include "nvme-subsys.h"
9 #define NVME_DEFAULT_ZONE_SIZE (128 * MiB)
10 #define NVME_DEFAULT_MAX_ZA_SIZE (128 * KiB)
12 typedef struct NvmeParams
{
14 uint32_t num_queues
; /* deprecated since 5.1 */
15 uint32_t max_ioqpairs
;
19 uint32_t aer_max_queued
;
27 typedef struct NvmeAsyncEvent
{
28 QTAILQ_ENTRY(NvmeAsyncEvent
) entry
;
33 NVME_SG_ALLOC
= 1 << 0,
37 typedef struct NvmeSg
{
46 typedef struct NvmeRequest
{
47 struct NvmeSQueue
*sq
;
48 struct NvmeNamespace
*ns
;
56 QTAILQ_ENTRY(NvmeRequest
)entry
;
59 typedef struct NvmeBounceContext
{
68 static inline const char *nvme_adm_opc_str(uint8_t 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
)
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
;
115 QTAILQ_HEAD(, NvmeRequest
) req_list
;
116 QTAILQ_HEAD(, NvmeRequest
) out_req_list
;
117 QTAILQ_ENTRY(NvmeSQueue
) entry
;
120 typedef struct NvmeCQueue
{
121 struct NvmeCtrl
*ctrl
;
124 uint16_t irq_enabled
;
131 QTAILQ_HEAD(, NvmeSQueue
) sq_list
;
132 QTAILQ_HEAD(, NvmeRequest
) req_list
;
135 #define TYPE_NVME_BUS "nvme-bus"
136 #define NVME_BUS(obj) OBJECT_CHECK(NvmeBus, (obj), TYPE_NVME_BUS)
138 typedef struct NvmeBus
{
142 #define TYPE_NVME "nvme"
144 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
146 typedef struct NvmeFeatureVal
{
148 uint16_t temp_thresh_hi
;
149 uint16_t temp_thresh_low
;
151 uint32_t async_config
;
154 typedef struct NvmeCtrl
{
155 PCIDevice parent_obj
;
166 uint16_t max_prp_ents
;
170 uint32_t num_namespaces
;
172 uint8_t outstanding_aers
;
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
;
188 HostMemoryBackend
*dev
;
194 NvmeRequest
**aer_reqs
;
195 QTAILQ_HEAD(, NvmeAsyncEvent
) aer_queue
;
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
];
217 NvmeFeatureVal features
;
220 static inline NvmeNamespace
*nvme_ns(NvmeCtrl
*n
, uint32_t nsid
)
222 if (!nsid
|| nsid
> n
->num_namespaces
) {
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
;
243 static inline uint16_t nvme_cid(NvmeRequest
*req
)
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,
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
,
266 #endif /* HW_NVME_H */