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