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