4 #include "block/nvme.h"
5 #include "nvme-subsys.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
{
21 uint32_t num_queues
; /* deprecated since 5.1 */
22 uint32_t max_ioqpairs
;
26 uint32_t aer_max_queued
;
33 typedef struct NvmeAsyncEvent
{
34 QTAILQ_ENTRY(NvmeAsyncEvent
) entry
;
39 NVME_SG_ALLOC
= 1 << 0,
43 typedef struct NvmeSg
{
52 typedef struct NvmeRequest
{
53 struct NvmeSQueue
*sq
;
54 struct NvmeNamespace
*ns
;
62 QTAILQ_ENTRY(NvmeRequest
)entry
;
65 static inline const char *nvme_adm_opc_str(uint8_t 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
)
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
;
109 QTAILQ_HEAD(, NvmeRequest
) req_list
;
110 QTAILQ_HEAD(, NvmeRequest
) out_req_list
;
111 QTAILQ_ENTRY(NvmeSQueue
) entry
;
114 typedef struct NvmeCQueue
{
115 struct NvmeCtrl
*ctrl
;
118 uint16_t irq_enabled
;
125 QTAILQ_HEAD(, NvmeSQueue
) sq_list
;
126 QTAILQ_HEAD(, NvmeRequest
) req_list
;
129 #define TYPE_NVME_BUS "nvme-bus"
130 #define NVME_BUS(obj) OBJECT_CHECK(NvmeBus, (obj), TYPE_NVME_BUS)
132 typedef struct NvmeBus
{
136 #define TYPE_NVME "nvme"
138 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
140 typedef struct NvmeFeatureVal
{
142 uint16_t temp_thresh_hi
;
143 uint16_t temp_thresh_low
;
145 uint32_t async_config
;
148 typedef struct NvmeCtrl
{
149 PCIDevice parent_obj
;
161 uint16_t max_prp_ents
;
165 uint32_t num_namespaces
;
167 uint8_t outstanding_aers
;
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
;
183 HostMemoryBackend
*dev
;
189 NvmeRequest
**aer_reqs
;
190 QTAILQ_HEAD(, NvmeAsyncEvent
) aer_queue
;
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
];
212 NvmeFeatureVal features
;
215 static inline NvmeNamespace
*nvme_ns(NvmeCtrl
*n
, uint32_t nsid
)
217 if (!nsid
|| nsid
> n
->num_namespaces
) {
221 return n
->namespaces
[nsid
- 1];
224 static inline bool nvme_ns_is_attached(NvmeCtrl
*n
, NvmeNamespace
*ns
)
228 for (nsid
= 1; nsid
<= n
->num_namespaces
; nsid
++) {
229 if (nvme_ns(n
, nsid
) == ns
) {
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
;
261 int nvme_register_namespace(NvmeCtrl
*n
, NvmeNamespace
*ns
, Error
**errp
);
263 #endif /* HW_NVME_H */