1788c47fcSHans Rosenfeld /* 2788c47fcSHans Rosenfeld * This file and its contents are supplied under the terms of the 3788c47fcSHans Rosenfeld * Common Development and Distribution License ("CDDL"), version 1.0. 4788c47fcSHans Rosenfeld * You may only use this file in accordance with the terms of version 5788c47fcSHans Rosenfeld * 1.0 of the CDDL. 6788c47fcSHans Rosenfeld * 7788c47fcSHans Rosenfeld * A full copy of the text of the CDDL should have accompanied this 8788c47fcSHans Rosenfeld * source. A copy of the CDDL is also available via the Internet at 9788c47fcSHans Rosenfeld * http://www.illumos.org/license/CDDL. 10788c47fcSHans Rosenfeld */ 11788c47fcSHans Rosenfeld 12788c47fcSHans Rosenfeld /* 136f37ecd5SHans Rosenfeld * Copyright 2016 Nexenta Systems, Inc. All rights reserved. 14b4eda73dSYouzhong Yang * Copyright 2016 The MathWorks, Inc. All rights reserved. 15ba636d1cSHans Rosenfeld * Copyright 2017 Joyent, Inc. 16788c47fcSHans Rosenfeld */ 17788c47fcSHans Rosenfeld 18788c47fcSHans Rosenfeld #ifndef _NVME_VAR_H 19788c47fcSHans Rosenfeld #define _NVME_VAR_H 20788c47fcSHans Rosenfeld 21788c47fcSHans Rosenfeld #include <sys/ddi.h> 22788c47fcSHans Rosenfeld #include <sys/sunddi.h> 23788c47fcSHans Rosenfeld #include <sys/blkdev.h> 24788c47fcSHans Rosenfeld #include <sys/taskq_impl.h> 25*69a33c23SHans Rosenfeld #include <sys/list.h> 26788c47fcSHans Rosenfeld 27788c47fcSHans Rosenfeld /* 28788c47fcSHans Rosenfeld * NVMe driver state 29788c47fcSHans Rosenfeld */ 30788c47fcSHans Rosenfeld 31788c47fcSHans Rosenfeld #ifdef __cplusplus 32032cbfebSHans Rosenfeld extern "C" { 33788c47fcSHans Rosenfeld #endif 34788c47fcSHans Rosenfeld 35788c47fcSHans Rosenfeld #define NVME_FMA_INIT 0x1 36788c47fcSHans Rosenfeld #define NVME_REGS_MAPPED 0x2 37788c47fcSHans Rosenfeld #define NVME_ADMIN_QUEUE 0x4 38788c47fcSHans Rosenfeld #define NVME_CTRL_LIMITS 0x8 39788c47fcSHans Rosenfeld #define NVME_INTERRUPTS 0x10 40788c47fcSHans Rosenfeld 41788c47fcSHans Rosenfeld #define NVME_MIN_ADMIN_QUEUE_LEN 16 42788c47fcSHans Rosenfeld #define NVME_MIN_IO_QUEUE_LEN 16 43788c47fcSHans Rosenfeld #define NVME_DEFAULT_ADMIN_QUEUE_LEN 256 44788c47fcSHans Rosenfeld #define NVME_DEFAULT_IO_QUEUE_LEN 1024 45788c47fcSHans Rosenfeld #define NVME_DEFAULT_ASYNC_EVENT_LIMIT 10 46788c47fcSHans Rosenfeld #define NVME_MIN_ASYNC_EVENT_LIMIT 1 479974ca0cSHans Rosenfeld #define NVME_DEFAULT_MIN_BLOCK_SIZE 512 48788c47fcSHans Rosenfeld 49788c47fcSHans Rosenfeld 50788c47fcSHans Rosenfeld typedef struct nvme nvme_t; 51788c47fcSHans Rosenfeld typedef struct nvme_namespace nvme_namespace_t; 52032cbfebSHans Rosenfeld typedef struct nvme_minor_state nvme_minor_state_t; 53788c47fcSHans Rosenfeld typedef struct nvme_dma nvme_dma_t; 54788c47fcSHans Rosenfeld typedef struct nvme_cmd nvme_cmd_t; 55788c47fcSHans Rosenfeld typedef struct nvme_qpair nvme_qpair_t; 56788c47fcSHans Rosenfeld typedef struct nvme_task_arg nvme_task_arg_t; 57788c47fcSHans Rosenfeld 58032cbfebSHans Rosenfeld struct nvme_minor_state { 59032cbfebSHans Rosenfeld kmutex_t nm_mutex; 60032cbfebSHans Rosenfeld boolean_t nm_oexcl; 61032cbfebSHans Rosenfeld uint_t nm_ocnt; 62032cbfebSHans Rosenfeld }; 63032cbfebSHans Rosenfeld 64788c47fcSHans Rosenfeld struct nvme_dma { 65788c47fcSHans Rosenfeld ddi_dma_handle_t nd_dmah; 66788c47fcSHans Rosenfeld ddi_acc_handle_t nd_acch; 67788c47fcSHans Rosenfeld ddi_dma_cookie_t nd_cookie; 68788c47fcSHans Rosenfeld uint_t nd_ncookie; 69788c47fcSHans Rosenfeld caddr_t nd_memp; 70788c47fcSHans Rosenfeld size_t nd_len; 71b4eda73dSYouzhong Yang boolean_t nd_cached; 72788c47fcSHans Rosenfeld }; 73788c47fcSHans Rosenfeld 74788c47fcSHans Rosenfeld struct nvme_cmd { 75*69a33c23SHans Rosenfeld struct list_node nc_list; 76*69a33c23SHans Rosenfeld 77788c47fcSHans Rosenfeld nvme_sqe_t nc_sqe; 78788c47fcSHans Rosenfeld nvme_cqe_t nc_cqe; 79788c47fcSHans Rosenfeld 80788c47fcSHans Rosenfeld void (*nc_callback)(void *); 81788c47fcSHans Rosenfeld bd_xfer_t *nc_xfer; 82788c47fcSHans Rosenfeld boolean_t nc_completed; 83032cbfebSHans Rosenfeld boolean_t nc_dontpanic; 84788c47fcSHans Rosenfeld uint16_t nc_sqid; 85788c47fcSHans Rosenfeld 86788c47fcSHans Rosenfeld nvme_dma_t *nc_dma; 87788c47fcSHans Rosenfeld 88788c47fcSHans Rosenfeld kmutex_t nc_mutex; 89788c47fcSHans Rosenfeld kcondvar_t nc_cv; 90788c47fcSHans Rosenfeld 91788c47fcSHans Rosenfeld taskq_ent_t nc_tqent; 92788c47fcSHans Rosenfeld nvme_t *nc_nvme; 93788c47fcSHans Rosenfeld }; 94788c47fcSHans Rosenfeld 95788c47fcSHans Rosenfeld struct nvme_qpair { 96788c47fcSHans Rosenfeld size_t nq_nentry; 97788c47fcSHans Rosenfeld 98788c47fcSHans Rosenfeld nvme_dma_t *nq_sqdma; 99788c47fcSHans Rosenfeld nvme_sqe_t *nq_sq; 100788c47fcSHans Rosenfeld uint_t nq_sqhead; 101788c47fcSHans Rosenfeld uint_t nq_sqtail; 102788c47fcSHans Rosenfeld uintptr_t nq_sqtdbl; 103788c47fcSHans Rosenfeld 104788c47fcSHans Rosenfeld nvme_dma_t *nq_cqdma; 105788c47fcSHans Rosenfeld nvme_cqe_t *nq_cq; 106788c47fcSHans Rosenfeld uint_t nq_cqhead; 107788c47fcSHans Rosenfeld uint_t nq_cqtail; 108788c47fcSHans Rosenfeld uintptr_t nq_cqhdbl; 109788c47fcSHans Rosenfeld 110788c47fcSHans Rosenfeld nvme_cmd_t **nq_cmd; 111788c47fcSHans Rosenfeld uint16_t nq_next_cmd; 112788c47fcSHans Rosenfeld uint_t nq_active_cmds; 113788c47fcSHans Rosenfeld int nq_phase; 114788c47fcSHans Rosenfeld 115788c47fcSHans Rosenfeld kmutex_t nq_mutex; 116ba636d1cSHans Rosenfeld ksema_t nq_sema; 117788c47fcSHans Rosenfeld }; 118788c47fcSHans Rosenfeld 119788c47fcSHans Rosenfeld struct nvme { 120788c47fcSHans Rosenfeld dev_info_t *n_dip; 121788c47fcSHans Rosenfeld int n_progress; 122788c47fcSHans Rosenfeld 123788c47fcSHans Rosenfeld caddr_t n_regs; 124788c47fcSHans Rosenfeld ddi_acc_handle_t n_regh; 125788c47fcSHans Rosenfeld 126788c47fcSHans Rosenfeld kmem_cache_t *n_cmd_cache; 127b4eda73dSYouzhong Yang kmem_cache_t *n_prp_cache; 128788c47fcSHans Rosenfeld 129788c47fcSHans Rosenfeld size_t n_inth_sz; 130788c47fcSHans Rosenfeld ddi_intr_handle_t *n_inth; 131788c47fcSHans Rosenfeld int n_intr_cnt; 132788c47fcSHans Rosenfeld uint_t n_intr_pri; 133788c47fcSHans Rosenfeld int n_intr_cap; 134788c47fcSHans Rosenfeld int n_intr_type; 135788c47fcSHans Rosenfeld int n_intr_types; 136788c47fcSHans Rosenfeld 137f0e4d8f0SHans Rosenfeld char *n_product; 138f0e4d8f0SHans Rosenfeld char *n_vendor; 139f0e4d8f0SHans Rosenfeld 140265d85e9SHans Rosenfeld nvme_version_t n_version; 141788c47fcSHans Rosenfeld boolean_t n_dead; 142788c47fcSHans Rosenfeld boolean_t n_strict_version; 143788c47fcSHans Rosenfeld boolean_t n_ignore_unknown_vendor_status; 144788c47fcSHans Rosenfeld uint32_t n_admin_queue_len; 145788c47fcSHans Rosenfeld uint32_t n_io_queue_len; 146788c47fcSHans Rosenfeld uint16_t n_async_event_limit; 1479974ca0cSHans Rosenfeld uint_t n_min_block_size; 148788c47fcSHans Rosenfeld uint16_t n_abort_command_limit; 149788c47fcSHans Rosenfeld uint64_t n_max_data_transfer_size; 1505f836503SHans Rosenfeld boolean_t n_write_cache_present; 1515f836503SHans Rosenfeld boolean_t n_write_cache_enabled; 152788c47fcSHans Rosenfeld int n_error_log_len; 153032cbfebSHans Rosenfeld boolean_t n_lba_range_supported; 154032cbfebSHans Rosenfeld boolean_t n_auto_pst_supported; 155788c47fcSHans Rosenfeld 156788c47fcSHans Rosenfeld int n_nssr_supported; 157788c47fcSHans Rosenfeld int n_doorbell_stride; 158788c47fcSHans Rosenfeld int n_timeout; 159788c47fcSHans Rosenfeld int n_arbitration_mechanisms; 160788c47fcSHans Rosenfeld int n_cont_queues_reqd; 161788c47fcSHans Rosenfeld int n_max_queue_entries; 162788c47fcSHans Rosenfeld int n_pageshift; 163788c47fcSHans Rosenfeld int n_pagesize; 164788c47fcSHans Rosenfeld 165788c47fcSHans Rosenfeld int n_namespace_count; 166*69a33c23SHans Rosenfeld uint16_t n_ioq_count; 167788c47fcSHans Rosenfeld 168788c47fcSHans Rosenfeld nvme_identify_ctrl_t *n_idctl; 169788c47fcSHans Rosenfeld 170788c47fcSHans Rosenfeld nvme_qpair_t *n_adminq; 171788c47fcSHans Rosenfeld nvme_qpair_t **n_ioq; 172788c47fcSHans Rosenfeld 173788c47fcSHans Rosenfeld nvme_namespace_t *n_ns; 174788c47fcSHans Rosenfeld 175788c47fcSHans Rosenfeld ddi_dma_attr_t n_queue_dma_attr; 176788c47fcSHans Rosenfeld ddi_dma_attr_t n_prp_dma_attr; 177788c47fcSHans Rosenfeld ddi_dma_attr_t n_sgl_dma_attr; 178788c47fcSHans Rosenfeld ddi_device_acc_attr_t n_reg_acc_attr; 179788c47fcSHans Rosenfeld ddi_iblock_cookie_t n_fm_ibc; 180788c47fcSHans Rosenfeld int n_fm_cap; 181788c47fcSHans Rosenfeld 182788c47fcSHans Rosenfeld ksema_t n_abort_sema; 183788c47fcSHans Rosenfeld 184788c47fcSHans Rosenfeld ddi_taskq_t *n_cmd_taskq; 185788c47fcSHans Rosenfeld 186032cbfebSHans Rosenfeld /* state for devctl minor node */ 187032cbfebSHans Rosenfeld nvme_minor_state_t n_minor; 188788c47fcSHans Rosenfeld 189788c47fcSHans Rosenfeld /* errors detected by driver */ 190788c47fcSHans Rosenfeld uint32_t n_dma_bind_err; 191788c47fcSHans Rosenfeld uint32_t n_abort_failed; 192788c47fcSHans Rosenfeld uint32_t n_cmd_timeout; 193788c47fcSHans Rosenfeld uint32_t n_cmd_aborted; 194788c47fcSHans Rosenfeld uint32_t n_wrong_logpage; 195788c47fcSHans Rosenfeld uint32_t n_unknown_logpage; 196788c47fcSHans Rosenfeld uint32_t n_too_many_cookies; 197788c47fcSHans Rosenfeld 198788c47fcSHans Rosenfeld /* errors detected by hardware */ 199788c47fcSHans Rosenfeld uint32_t n_data_xfr_err; 200788c47fcSHans Rosenfeld uint32_t n_internal_err; 201788c47fcSHans Rosenfeld uint32_t n_abort_rq_err; 202788c47fcSHans Rosenfeld uint32_t n_abort_sq_del; 203788c47fcSHans Rosenfeld uint32_t n_nvm_cap_exc; 204788c47fcSHans Rosenfeld uint32_t n_nvm_ns_notrdy; 205788c47fcSHans Rosenfeld uint32_t n_inv_cq_err; 206788c47fcSHans Rosenfeld uint32_t n_inv_qid_err; 207788c47fcSHans Rosenfeld uint32_t n_max_qsz_exc; 208788c47fcSHans Rosenfeld uint32_t n_inv_int_vect; 209788c47fcSHans Rosenfeld uint32_t n_inv_log_page; 210788c47fcSHans Rosenfeld uint32_t n_inv_format; 211788c47fcSHans Rosenfeld uint32_t n_inv_q_del; 212788c47fcSHans Rosenfeld uint32_t n_cnfl_attr; 213788c47fcSHans Rosenfeld uint32_t n_inv_prot; 214788c47fcSHans Rosenfeld uint32_t n_readonly; 215788c47fcSHans Rosenfeld 216788c47fcSHans Rosenfeld /* errors reported by asynchronous events */ 217788c47fcSHans Rosenfeld uint32_t n_diagfail_event; 218788c47fcSHans Rosenfeld uint32_t n_persistent_event; 219788c47fcSHans Rosenfeld uint32_t n_transient_event; 220788c47fcSHans Rosenfeld uint32_t n_fw_load_event; 221788c47fcSHans Rosenfeld uint32_t n_reliability_event; 222788c47fcSHans Rosenfeld uint32_t n_temperature_event; 223788c47fcSHans Rosenfeld uint32_t n_spare_event; 224788c47fcSHans Rosenfeld uint32_t n_vendor_event; 225788c47fcSHans Rosenfeld uint32_t n_unknown_event; 226788c47fcSHans Rosenfeld 227788c47fcSHans Rosenfeld }; 228788c47fcSHans Rosenfeld 229788c47fcSHans Rosenfeld struct nvme_namespace { 230788c47fcSHans Rosenfeld nvme_t *ns_nvme; 231265d85e9SHans Rosenfeld uint8_t ns_eui64[8]; 232032cbfebSHans Rosenfeld char ns_name[17]; 233265d85e9SHans Rosenfeld 234788c47fcSHans Rosenfeld bd_handle_t ns_bd_hdl; 235788c47fcSHans Rosenfeld 236788c47fcSHans Rosenfeld uint32_t ns_id; 237788c47fcSHans Rosenfeld size_t ns_block_count; 238788c47fcSHans Rosenfeld size_t ns_block_size; 239788c47fcSHans Rosenfeld size_t ns_best_block_size; 240788c47fcSHans Rosenfeld 241788c47fcSHans Rosenfeld boolean_t ns_ignore; 242788c47fcSHans Rosenfeld 243788c47fcSHans Rosenfeld nvme_identify_nsid_t *ns_idns; 244788c47fcSHans Rosenfeld 245032cbfebSHans Rosenfeld /* state for attachment point minor node */ 246032cbfebSHans Rosenfeld nvme_minor_state_t ns_minor; 247032cbfebSHans Rosenfeld 248788c47fcSHans Rosenfeld /* 249265d85e9SHans Rosenfeld * If a namespace has no EUI64, we create a devid in 250265d85e9SHans Rosenfeld * nvme_prepare_devid(). 251788c47fcSHans Rosenfeld */ 252265d85e9SHans Rosenfeld char *ns_devid; 253788c47fcSHans Rosenfeld }; 254788c47fcSHans Rosenfeld 255788c47fcSHans Rosenfeld struct nvme_task_arg { 256788c47fcSHans Rosenfeld nvme_t *nt_nvme; 257788c47fcSHans Rosenfeld nvme_cmd_t *nt_cmd; 258788c47fcSHans Rosenfeld }; 259788c47fcSHans Rosenfeld 260032cbfebSHans Rosenfeld 261788c47fcSHans Rosenfeld #ifdef __cplusplus 262032cbfebSHans Rosenfeld } 263788c47fcSHans Rosenfeld #endif 264788c47fcSHans Rosenfeld 265788c47fcSHans Rosenfeld #endif /* _NVME_VAR_H */ 266