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