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  */
  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 
  46 typedef struct nvme nvme_t;
  47 typedef struct nvme_namespace nvme_namespace_t;
  48 typedef struct nvme_dma nvme_dma_t;
  49 typedef struct nvme_cmd nvme_cmd_t;
  50 typedef struct nvme_qpair nvme_qpair_t;
  51 typedef struct nvme_task_arg nvme_task_arg_t;
  52 
  53 struct nvme_dma {
  54         ddi_dma_handle_t nd_dmah;
  55         ddi_acc_handle_t nd_acch;
  56         ddi_dma_cookie_t nd_cookie;
  57         uint_t nd_ncookie;
  58         caddr_t nd_memp;
  59         size_t nd_len;
  60 };
  61 
  62 struct nvme_cmd {
  63         nvme_sqe_t nc_sqe;
  64         nvme_cqe_t nc_cqe;
  65 
  66         void (*nc_callback)(void *);
  67         bd_xfer_t *nc_xfer;
  68         boolean_t nc_completed;
  69         uint16_t nc_sqid;
  70 
  71         nvme_dma_t *nc_dma;
  72 
  73         kmutex_t nc_mutex;
  74         kcondvar_t nc_cv;
  75 
  76         taskq_ent_t nc_tqent;
  77         nvme_t *nc_nvme;
  78 };
  79 
  80 struct nvme_qpair {
  81         size_t nq_nentry;
  82 
  83         nvme_dma_t *nq_sqdma;
  84         nvme_sqe_t *nq_sq;
  85         uint_t nq_sqhead;
  86         uint_t nq_sqtail;
  87         uintptr_t nq_sqtdbl;
  88 
  89         nvme_dma_t *nq_cqdma;
  90         nvme_cqe_t *nq_cq;
  91         uint_t nq_cqhead;
  92         uint_t nq_cqtail;
  93         uintptr_t nq_cqhdbl;
  94 
  95         nvme_cmd_t **nq_cmd;
  96         uint16_t nq_next_cmd;
  97         uint_t nq_active_cmds;
  98         int nq_phase;
  99 
 100         kmutex_t nq_mutex;
 101         hrtime_t nq_ts;
 102         list_node_t nq_list_node;
 103         nvme_t *nq_nvme;
 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 
 115         size_t n_inth_sz;
 116         ddi_intr_handle_t *n_inth;
 117         int n_intr_cnt;
 118         uint_t n_intr_pri;
 119         int n_intr_cap;
 120         int n_intr_type;
 121         int n_intr_types;
 122         int n_intr_timeouts;
 123 
 124         char *n_product;
 125         char *n_vendor;
 126 
 127         boolean_t n_dead;
 128         boolean_t n_strict_version;
 129         boolean_t n_ignore_unknown_vendor_status;
 130         uint32_t n_admin_queue_len;
 131         uint32_t n_io_queue_len;
 132         uint16_t n_async_event_limit;
 133         uint16_t n_abort_command_limit;
 134         uint64_t n_max_data_transfer_size;
 135         boolean_t n_volatile_write_cache_enabled;
 136         int n_error_log_len;
 137 
 138         int n_nssr_supported;
 139         int n_doorbell_stride;
 140         int n_timeout;
 141         int n_arbitration_mechanisms;
 142         int n_cont_queues_reqd;
 143         int n_max_queue_entries;
 144         int n_pageshift;
 145         int n_pagesize;
 146 
 147         int n_namespace_count;
 148         int n_ioq_count;
 149 
 150         nvme_identify_ctrl_t *n_idctl;
 151 
 152         nvme_qpair_t *n_adminq;
 153         nvme_qpair_t **n_ioq;
 154 
 155         nvme_namespace_t *n_ns;
 156 
 157         ddi_dma_attr_t n_queue_dma_attr;
 158         ddi_dma_attr_t n_prp_dma_attr;
 159         ddi_dma_attr_t n_sgl_dma_attr;
 160         ddi_device_acc_attr_t n_reg_acc_attr;
 161         ddi_iblock_cookie_t n_fm_ibc;
 162         int n_fm_cap;
 163 
 164         ksema_t n_abort_sema;
 165 
 166         ddi_taskq_t *n_cmd_taskq;
 167 
 168         nvme_error_log_entry_t *n_error_log;
 169         nvme_health_log_t *n_health_log;
 170         nvme_fwslot_log_t *n_fwslot_log;
 171 
 172         /* errors detected by driver */
 173         uint32_t n_dma_bind_err;
 174         uint32_t n_abort_failed;
 175         uint32_t n_cmd_timeout;
 176         uint32_t n_cmd_aborted;
 177         uint32_t n_async_resubmit_failed;
 178         uint32_t n_wrong_logpage;
 179         uint32_t n_unknown_logpage;
 180         uint32_t n_too_many_cookies;
 181         uint32_t n_admin_queue_full;
 182 
 183         /* errors detected by hardware */
 184         uint32_t n_data_xfr_err;
 185         uint32_t n_internal_err;
 186         uint32_t n_abort_rq_err;
 187         uint32_t n_abort_sq_del;
 188         uint32_t n_nvm_cap_exc;
 189         uint32_t n_nvm_ns_notrdy;
 190         uint32_t n_inv_cq_err;
 191         uint32_t n_inv_qid_err;
 192         uint32_t n_max_qsz_exc;
 193         uint32_t n_inv_int_vect;
 194         uint32_t n_inv_log_page;
 195         uint32_t n_inv_format;
 196         uint32_t n_inv_q_del;
 197         uint32_t n_cnfl_attr;
 198         uint32_t n_inv_prot;
 199         uint32_t n_readonly;
 200 
 201         /* errors reported by asynchronous events */
 202         uint32_t n_diagfail_event;
 203         uint32_t n_persistent_event;
 204         uint32_t n_transient_event;
 205         uint32_t n_fw_load_event;
 206         uint32_t n_reliability_event;
 207         uint32_t n_temperature_event;
 208         uint32_t n_spare_event;
 209         uint32_t n_vendor_event;
 210         uint32_t n_unknown_event;
 211 
 212 };
 213 
 214 struct nvme_namespace {
 215         nvme_t *ns_nvme;
 216         bd_handle_t ns_bd_hdl;
 217 
 218         uint32_t ns_id;
 219         size_t ns_block_count;
 220         size_t ns_block_size;
 221         size_t ns_best_block_size;
 222 
 223         boolean_t ns_ignore;
 224 
 225         nvme_identify_nsid_t *ns_idns;
 226 
 227         /*
 228          * Section 7.7 of the spec describes how to get a unique ID for
 229          * the controller: the vendor ID, the model name and the serial
 230          * number shall be unique when combined.
 231          *
 232          * We add the hex namespace ID to get a unique ID for the namespace.
 233          */
 234         char ns_devid[4 + 1 + 20 + 1 + 40 + 1 + 8 + 1];
 235 };
 236 
 237 struct nvme_task_arg {
 238         nvme_t *nt_nvme;
 239         nvme_cmd_t *nt_cmd;
 240 };
 241 
 242 #ifdef __cplusplus
 243 /* } */
 244 #endif
 245 
 246 #endif /* _NVME_VAR_H */