xref: /illumos-gate/usr/src/uts/common/io/nvme/nvme_var.h (revision 2c5ec7a875dcd76853e6618614e990f1e8cdd56d)
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 2017 Joyent, Inc.
16  */
17 
18 #ifndef _NVME_VAR_H
19 #define	_NVME_VAR_H
20 
21 #include <sys/ddi.h>
22 #include <sys/sunddi.h>
23 #include <sys/blkdev.h>
24 #include <sys/taskq_impl.h>
25 #include <sys/list.h>
26 
27 /*
28  * NVMe driver state
29  */
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 #define	NVME_FMA_INIT			0x1
36 #define	NVME_REGS_MAPPED 		0x2
37 #define	NVME_ADMIN_QUEUE 		0x4
38 #define	NVME_CTRL_LIMITS 		0x8
39 #define	NVME_INTERRUPTS  		0x10
40 
41 #define	NVME_MIN_ADMIN_QUEUE_LEN	16
42 #define	NVME_MIN_IO_QUEUE_LEN		16
43 #define	NVME_DEFAULT_ADMIN_QUEUE_LEN	256
44 #define	NVME_DEFAULT_IO_QUEUE_LEN	1024
45 #define	NVME_DEFAULT_ASYNC_EVENT_LIMIT	10
46 #define	NVME_MIN_ASYNC_EVENT_LIMIT	1
47 #define	NVME_DEFAULT_MIN_BLOCK_SIZE	512
48 
49 
50 typedef struct nvme nvme_t;
51 typedef struct nvme_namespace nvme_namespace_t;
52 typedef struct nvme_minor_state nvme_minor_state_t;
53 typedef struct nvme_dma nvme_dma_t;
54 typedef struct nvme_cmd nvme_cmd_t;
55 typedef struct nvme_qpair nvme_qpair_t;
56 typedef struct nvme_task_arg nvme_task_arg_t;
57 
58 struct nvme_minor_state {
59 	kmutex_t	nm_mutex;
60 	boolean_t	nm_oexcl;
61 	uint_t		nm_ocnt;
62 };
63 
64 struct nvme_dma {
65 	ddi_dma_handle_t nd_dmah;
66 	ddi_acc_handle_t nd_acch;
67 	ddi_dma_cookie_t nd_cookie;
68 	uint_t nd_ncookie;
69 	caddr_t nd_memp;
70 	size_t nd_len;
71 	boolean_t nd_cached;
72 };
73 
74 struct nvme_cmd {
75 	struct list_node nc_list;
76 
77 	nvme_sqe_t nc_sqe;
78 	nvme_cqe_t nc_cqe;
79 
80 	void (*nc_callback)(void *);
81 	bd_xfer_t *nc_xfer;
82 	boolean_t nc_completed;
83 	boolean_t nc_dontpanic;
84 	uint16_t nc_sqid;
85 
86 	nvme_dma_t *nc_dma;
87 
88 	kmutex_t nc_mutex;
89 	kcondvar_t nc_cv;
90 
91 	taskq_ent_t nc_tqent;
92 	nvme_t *nc_nvme;
93 };
94 
95 struct nvme_qpair {
96 	size_t nq_nentry;
97 
98 	nvme_dma_t *nq_sqdma;
99 	nvme_sqe_t *nq_sq;
100 	uint_t nq_sqhead;
101 	uint_t nq_sqtail;
102 	uintptr_t nq_sqtdbl;
103 
104 	nvme_dma_t *nq_cqdma;
105 	nvme_cqe_t *nq_cq;
106 	uint_t nq_cqhead;
107 	uint_t nq_cqtail;
108 	uintptr_t nq_cqhdbl;
109 
110 	nvme_cmd_t **nq_cmd;
111 	uint16_t nq_next_cmd;
112 	uint_t nq_active_cmds;
113 	int nq_phase;
114 
115 	kmutex_t nq_mutex;
116 	ksema_t nq_sema;
117 };
118 
119 struct nvme {
120 	dev_info_t *n_dip;
121 	int n_progress;
122 
123 	caddr_t n_regs;
124 	ddi_acc_handle_t n_regh;
125 
126 	kmem_cache_t *n_cmd_cache;
127 	kmem_cache_t *n_prp_cache;
128 
129 	size_t n_inth_sz;
130 	ddi_intr_handle_t *n_inth;
131 	int n_intr_cnt;
132 	uint_t n_intr_pri;
133 	int n_intr_cap;
134 	int n_intr_type;
135 	int n_intr_types;
136 
137 	char *n_product;
138 	char *n_vendor;
139 
140 	nvme_version_t n_version;
141 	boolean_t n_dead;
142 	boolean_t n_strict_version;
143 	boolean_t n_ignore_unknown_vendor_status;
144 	uint32_t n_admin_queue_len;
145 	uint32_t n_io_queue_len;
146 	uint16_t n_async_event_limit;
147 	uint_t n_min_block_size;
148 	uint16_t n_abort_command_limit;
149 	uint64_t n_max_data_transfer_size;
150 	boolean_t n_write_cache_present;
151 	boolean_t n_write_cache_enabled;
152 	int n_error_log_len;
153 	boolean_t n_lba_range_supported;
154 	boolean_t n_auto_pst_supported;
155 	boolean_t n_async_event_supported;
156 	boolean_t n_progress_supported;
157 
158 	int n_nssr_supported;
159 	int n_doorbell_stride;
160 	int n_timeout;
161 	int n_arbitration_mechanisms;
162 	int n_cont_queues_reqd;
163 	int n_max_queue_entries;
164 	int n_pageshift;
165 	int n_pagesize;
166 
167 	int n_namespace_count;
168 	uint16_t n_ioq_count;
169 
170 	nvme_identify_ctrl_t *n_idctl;
171 
172 	nvme_qpair_t *n_adminq;
173 	nvme_qpair_t **n_ioq;
174 
175 	nvme_namespace_t *n_ns;
176 
177 	ddi_dma_attr_t n_queue_dma_attr;
178 	ddi_dma_attr_t n_prp_dma_attr;
179 	ddi_dma_attr_t n_sgl_dma_attr;
180 	ddi_device_acc_attr_t n_reg_acc_attr;
181 	ddi_iblock_cookie_t n_fm_ibc;
182 	int n_fm_cap;
183 
184 	ksema_t n_abort_sema;
185 
186 	ddi_taskq_t *n_cmd_taskq;
187 
188 	/* state for devctl minor node */
189 	nvme_minor_state_t n_minor;
190 
191 	/* errors detected by driver */
192 	uint32_t n_dma_bind_err;
193 	uint32_t n_abort_failed;
194 	uint32_t n_cmd_timeout;
195 	uint32_t n_cmd_aborted;
196 	uint32_t n_wrong_logpage;
197 	uint32_t n_unknown_logpage;
198 	uint32_t n_too_many_cookies;
199 
200 	/* errors detected by hardware */
201 	uint32_t n_data_xfr_err;
202 	uint32_t n_internal_err;
203 	uint32_t n_abort_rq_err;
204 	uint32_t n_abort_sq_del;
205 	uint32_t n_nvm_cap_exc;
206 	uint32_t n_nvm_ns_notrdy;
207 	uint32_t n_inv_cq_err;
208 	uint32_t n_inv_qid_err;
209 	uint32_t n_max_qsz_exc;
210 	uint32_t n_inv_int_vect;
211 	uint32_t n_inv_log_page;
212 	uint32_t n_inv_format;
213 	uint32_t n_inv_q_del;
214 	uint32_t n_cnfl_attr;
215 	uint32_t n_inv_prot;
216 	uint32_t n_readonly;
217 
218 	/* errors reported by asynchronous events */
219 	uint32_t n_diagfail_event;
220 	uint32_t n_persistent_event;
221 	uint32_t n_transient_event;
222 	uint32_t n_fw_load_event;
223 	uint32_t n_reliability_event;
224 	uint32_t n_temperature_event;
225 	uint32_t n_spare_event;
226 	uint32_t n_vendor_event;
227 	uint32_t n_unknown_event;
228 
229 };
230 
231 struct nvme_namespace {
232 	nvme_t *ns_nvme;
233 	uint8_t ns_eui64[8];
234 	char	ns_name[17];
235 
236 	bd_handle_t ns_bd_hdl;
237 
238 	uint32_t ns_id;
239 	size_t ns_block_count;
240 	size_t ns_block_size;
241 	size_t ns_best_block_size;
242 
243 	boolean_t ns_ignore;
244 
245 	nvme_identify_nsid_t *ns_idns;
246 
247 	/* state for attachment point minor node */
248 	nvme_minor_state_t ns_minor;
249 
250 	/*
251 	 * If a namespace has no EUI64, we create a devid in
252 	 * nvme_prepare_devid().
253 	 */
254 	char *ns_devid;
255 };
256 
257 struct nvme_task_arg {
258 	nvme_t *nt_nvme;
259 	nvme_cmd_t *nt_cmd;
260 };
261 
262 
263 #ifdef __cplusplus
264 }
265 #endif
266 
267 #endif /* _NVME_VAR_H */
268