xref: /illumos-gate/usr/src/uts/common/io/nvme/nvme_var.h (revision b69c34dad3717624ff6b4f32b71014ee05b6a678)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2018 Nexenta Systems, Inc.
14  * Copyright 2016 The MathWorks, Inc. All rights reserved.
15  * Copyright 2019 Joyent, Inc.
16  * Copyright 2019 Western Digital Corporation.
17  */
18 
19 #ifndef _NVME_VAR_H
20 #define	_NVME_VAR_H
21 
22 #include <sys/ddi.h>
23 #include <sys/sunddi.h>
24 #include <sys/blkdev.h>
25 #include <sys/taskq_impl.h>
26 #include <sys/list.h>
27 
28 /*
29  * NVMe driver state
30  */
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #define	NVME_FMA_INIT			0x1
37 #define	NVME_REGS_MAPPED		0x2
38 #define	NVME_ADMIN_QUEUE		0x4
39 #define	NVME_CTRL_LIMITS		0x8
40 #define	NVME_INTERRUPTS			0x10
41 #define	NVME_UFM_INIT			0x20
42 
43 #define	NVME_MIN_ADMIN_QUEUE_LEN	16
44 #define	NVME_MIN_IO_QUEUE_LEN		16
45 #define	NVME_DEFAULT_ADMIN_QUEUE_LEN	256
46 #define	NVME_DEFAULT_IO_QUEUE_LEN	1024
47 #define	NVME_DEFAULT_ASYNC_EVENT_LIMIT	10
48 #define	NVME_MIN_ASYNC_EVENT_LIMIT	1
49 #define	NVME_DEFAULT_MIN_BLOCK_SIZE	512
50 
51 
52 typedef struct nvme nvme_t;
53 typedef struct nvme_namespace nvme_namespace_t;
54 typedef struct nvme_minor_state nvme_minor_state_t;
55 typedef struct nvme_dma nvme_dma_t;
56 typedef struct nvme_cmd nvme_cmd_t;
57 typedef struct nvme_cq nvme_cq_t;
58 typedef struct nvme_qpair nvme_qpair_t;
59 typedef struct nvme_task_arg nvme_task_arg_t;
60 
61 struct nvme_minor_state {
62 	kmutex_t	nm_mutex;
63 	boolean_t	nm_oexcl;
64 	uint_t		nm_ocnt;
65 };
66 
67 struct nvme_dma {
68 	ddi_dma_handle_t nd_dmah;
69 	ddi_acc_handle_t nd_acch;
70 	ddi_dma_cookie_t nd_cookie;
71 	uint_t nd_ncookie;
72 	caddr_t nd_memp;
73 	size_t nd_len;
74 	boolean_t nd_cached;
75 };
76 
77 struct nvme_cmd {
78 	struct list_node nc_list;
79 
80 	nvme_sqe_t nc_sqe;
81 	nvme_cqe_t nc_cqe;
82 
83 	void (*nc_callback)(void *);
84 	bd_xfer_t *nc_xfer;
85 	boolean_t nc_completed;
86 	boolean_t nc_dontpanic;
87 	uint16_t nc_sqid;
88 
89 	nvme_dma_t *nc_dma;
90 
91 	kmutex_t nc_mutex;
92 	kcondvar_t nc_cv;
93 
94 	taskq_ent_t nc_tqent;
95 	nvme_t *nc_nvme;
96 };
97 
98 struct nvme_cq {
99 	size_t ncq_nentry;
100 	uint16_t ncq_id;
101 
102 	nvme_dma_t *ncq_dma;
103 	nvme_cqe_t *ncq_cq;
104 	uint_t ncq_head;
105 	uint_t ncq_tail;
106 	uintptr_t ncq_hdbl;
107 	int ncq_phase;
108 
109 	taskq_t *ncq_cmd_taskq;
110 
111 	kmutex_t ncq_mutex;
112 };
113 
114 struct nvme_qpair {
115 	size_t nq_nentry;
116 
117 	nvme_dma_t *nq_sqdma;
118 	nvme_sqe_t *nq_sq;
119 	uint_t nq_sqhead;
120 	uint_t nq_sqtail;
121 	uintptr_t nq_sqtdbl;
122 
123 	nvme_cq_t *nq_cq;
124 
125 	nvme_cmd_t **nq_cmd;
126 	uint16_t nq_next_cmd;
127 	uint_t nq_active_cmds;
128 
129 	kmutex_t nq_mutex;
130 	ksema_t nq_sema;
131 };
132 
133 struct nvme {
134 	dev_info_t *n_dip;
135 	int n_progress;
136 
137 	caddr_t n_regs;
138 	ddi_acc_handle_t n_regh;
139 
140 	kmem_cache_t *n_cmd_cache;
141 	kmem_cache_t *n_prp_cache;
142 
143 	size_t n_inth_sz;
144 	ddi_intr_handle_t *n_inth;
145 	int n_intr_cnt;
146 	uint_t n_intr_pri;
147 	int n_intr_cap;
148 	int n_intr_type;
149 	int n_intr_types;
150 
151 	char *n_product;
152 	char *n_vendor;
153 
154 	nvme_version_t n_version;
155 	boolean_t n_dead;
156 	boolean_t n_strict_version;
157 	boolean_t n_ignore_unknown_vendor_status;
158 	uint32_t n_admin_queue_len;
159 	uint32_t n_io_squeue_len;
160 	uint32_t n_io_cqueue_len;
161 	uint16_t n_async_event_limit;
162 	uint_t n_min_block_size;
163 	uint16_t n_abort_command_limit;
164 	uint64_t n_max_data_transfer_size;
165 	boolean_t n_write_cache_present;
166 	boolean_t n_write_cache_enabled;
167 	int n_error_log_len;
168 	boolean_t n_lba_range_supported;
169 	boolean_t n_auto_pst_supported;
170 	boolean_t n_async_event_supported;
171 	boolean_t n_progress_supported;
172 	int n_submission_queues;
173 	int n_completion_queues;
174 
175 	int n_nssr_supported;
176 	int n_doorbell_stride;
177 	int n_timeout;
178 	int n_arbitration_mechanisms;
179 	int n_cont_queues_reqd;
180 	int n_max_queue_entries;
181 	int n_pageshift;
182 	int n_pagesize;
183 
184 	int n_namespace_count;
185 	uint_t n_namespaces_attachable;
186 	uint_t n_ioq_count;
187 	uint_t n_cq_count;
188 
189 	nvme_identify_ctrl_t *n_idctl;
190 
191 	nvme_qpair_t *n_adminq;
192 	nvme_qpair_t **n_ioq;
193 	nvme_cq_t **n_cq;
194 
195 	nvme_namespace_t *n_ns;
196 
197 	ddi_dma_attr_t n_queue_dma_attr;
198 	ddi_dma_attr_t n_prp_dma_attr;
199 	ddi_dma_attr_t n_sgl_dma_attr;
200 	ddi_device_acc_attr_t n_reg_acc_attr;
201 	ddi_iblock_cookie_t n_fm_ibc;
202 	int n_fm_cap;
203 
204 	ksema_t n_abort_sema;
205 
206 	/* state for devctl minor node */
207 	nvme_minor_state_t n_minor;
208 
209 	/* errors detected by driver */
210 	uint32_t n_dma_bind_err;
211 	uint32_t n_abort_failed;
212 	uint32_t n_cmd_timeout;
213 	uint32_t n_cmd_aborted;
214 	uint32_t n_wrong_logpage;
215 	uint32_t n_unknown_logpage;
216 	uint32_t n_too_many_cookies;
217 
218 	/* errors detected by hardware */
219 	uint32_t n_data_xfr_err;
220 	uint32_t n_internal_err;
221 	uint32_t n_abort_rq_err;
222 	uint32_t n_abort_sq_del;
223 	uint32_t n_nvm_cap_exc;
224 	uint32_t n_nvm_ns_notrdy;
225 	uint32_t n_inv_cq_err;
226 	uint32_t n_inv_qid_err;
227 	uint32_t n_max_qsz_exc;
228 	uint32_t n_inv_int_vect;
229 	uint32_t n_inv_log_page;
230 	uint32_t n_inv_format;
231 	uint32_t n_inv_q_del;
232 	uint32_t n_cnfl_attr;
233 	uint32_t n_inv_prot;
234 	uint32_t n_readonly;
235 
236 	/* errors reported by asynchronous events */
237 	uint32_t n_diagfail_event;
238 	uint32_t n_persistent_event;
239 	uint32_t n_transient_event;
240 	uint32_t n_fw_load_event;
241 	uint32_t n_reliability_event;
242 	uint32_t n_temperature_event;
243 	uint32_t n_spare_event;
244 	uint32_t n_vendor_event;
245 	uint32_t n_unknown_event;
246 
247 	/* DDI UFM handle */
248 	ddi_ufm_handle_t *n_ufmh;
249 	/* Cached Firmware Slot Information log page */
250 	nvme_fwslot_log_t *n_fwslot;
251 	/* Lock protecting the cached firmware slot info */
252 	kmutex_t n_fwslot_mutex;
253 };
254 
255 struct nvme_namespace {
256 	nvme_t *ns_nvme;
257 	uint8_t ns_eui64[8];
258 	char	ns_name[17];
259 
260 	bd_handle_t ns_bd_hdl;
261 
262 	uint32_t ns_id;
263 	size_t ns_block_count;
264 	size_t ns_block_size;
265 	size_t ns_best_block_size;
266 
267 	boolean_t ns_ignore;
268 
269 	nvme_identify_nsid_t *ns_idns;
270 
271 	/* state for attachment point minor node */
272 	nvme_minor_state_t ns_minor;
273 
274 	/*
275 	 * If a namespace has no EUI64, we create a devid in
276 	 * nvme_prepare_devid().
277 	 */
278 	char *ns_devid;
279 };
280 
281 struct nvme_task_arg {
282 	nvme_t *nt_nvme;
283 	nvme_cmd_t *nt_cmd;
284 };
285 
286 #ifdef __cplusplus
287 }
288 #endif
289 
290 #endif /* _NVME_VAR_H */
291