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 * 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 157 int n_nssr_supported; 158 int n_doorbell_stride; 159 int n_timeout; 160 int n_arbitration_mechanisms; 161 int n_cont_queues_reqd; 162 int n_max_queue_entries; 163 int n_pageshift; 164 int n_pagesize; 165 166 int n_namespace_count; 167 uint16_t n_ioq_count; 168 169 nvme_identify_ctrl_t *n_idctl; 170 171 nvme_qpair_t *n_adminq; 172 nvme_qpair_t **n_ioq; 173 174 nvme_namespace_t *n_ns; 175 176 ddi_dma_attr_t n_queue_dma_attr; 177 ddi_dma_attr_t n_prp_dma_attr; 178 ddi_dma_attr_t n_sgl_dma_attr; 179 ddi_device_acc_attr_t n_reg_acc_attr; 180 ddi_iblock_cookie_t n_fm_ibc; 181 int n_fm_cap; 182 183 ksema_t n_abort_sema; 184 185 ddi_taskq_t *n_cmd_taskq; 186 187 /* state for devctl minor node */ 188 nvme_minor_state_t n_minor; 189 190 /* errors detected by driver */ 191 uint32_t n_dma_bind_err; 192 uint32_t n_abort_failed; 193 uint32_t n_cmd_timeout; 194 uint32_t n_cmd_aborted; 195 uint32_t n_wrong_logpage; 196 uint32_t n_unknown_logpage; 197 uint32_t n_too_many_cookies; 198 199 /* errors detected by hardware */ 200 uint32_t n_data_xfr_err; 201 uint32_t n_internal_err; 202 uint32_t n_abort_rq_err; 203 uint32_t n_abort_sq_del; 204 uint32_t n_nvm_cap_exc; 205 uint32_t n_nvm_ns_notrdy; 206 uint32_t n_inv_cq_err; 207 uint32_t n_inv_qid_err; 208 uint32_t n_max_qsz_exc; 209 uint32_t n_inv_int_vect; 210 uint32_t n_inv_log_page; 211 uint32_t n_inv_format; 212 uint32_t n_inv_q_del; 213 uint32_t n_cnfl_attr; 214 uint32_t n_inv_prot; 215 uint32_t n_readonly; 216 217 /* errors reported by asynchronous events */ 218 uint32_t n_diagfail_event; 219 uint32_t n_persistent_event; 220 uint32_t n_transient_event; 221 uint32_t n_fw_load_event; 222 uint32_t n_reliability_event; 223 uint32_t n_temperature_event; 224 uint32_t n_spare_event; 225 uint32_t n_vendor_event; 226 uint32_t n_unknown_event; 227 228 }; 229 230 struct nvme_namespace { 231 nvme_t *ns_nvme; 232 uint8_t ns_eui64[8]; 233 char ns_name[17]; 234 235 bd_handle_t ns_bd_hdl; 236 237 uint32_t ns_id; 238 size_t ns_block_count; 239 size_t ns_block_size; 240 size_t ns_best_block_size; 241 242 boolean_t ns_ignore; 243 244 nvme_identify_nsid_t *ns_idns; 245 246 /* state for attachment point minor node */ 247 nvme_minor_state_t ns_minor; 248 249 /* 250 * If a namespace has no EUI64, we create a devid in 251 * nvme_prepare_devid(). 252 */ 253 char *ns_devid; 254 }; 255 256 struct nvme_task_arg { 257 nvme_t *nt_nvme; 258 nvme_cmd_t *nt_cmd; 259 }; 260 261 262 #ifdef __cplusplus 263 } 264 #endif 265 266 #endif /* _NVME_VAR_H */ 267