13c9168faSHans Rosenfeld /* 23c9168faSHans Rosenfeld * This file and its contents are supplied under the terms of the 33c9168faSHans Rosenfeld * Common Development and Distribution License ("CDDL"), version 1.0. 43c9168faSHans Rosenfeld * You may only use this file in accordance with the terms of version 53c9168faSHans Rosenfeld * 1.0 of the CDDL. 63c9168faSHans Rosenfeld * 73c9168faSHans Rosenfeld * A full copy of the text of the CDDL should have accompanied this 83c9168faSHans Rosenfeld * source. A copy of the CDDL is also available via the Internet at 93c9168faSHans Rosenfeld * http://www.illumos.org/license/CDDL. 103c9168faSHans Rosenfeld */ 113c9168faSHans Rosenfeld 123c9168faSHans Rosenfeld /* 13fcc62af7SHans Rosenfeld * Copyright 2016 Nexenta Systems, Inc. All rights reserved. 14582eef8cSYouzhong Yang * Copyright 2016 The MathWorks, Inc. All rights reserved. 15adec8d5dSHans Rosenfeld * Copyright 2017 Joyent, Inc. 163c9168faSHans Rosenfeld */ 173c9168faSHans Rosenfeld 183c9168faSHans Rosenfeld #ifndef _NVME_VAR_H 193c9168faSHans Rosenfeld #define _NVME_VAR_H 203c9168faSHans Rosenfeld 213c9168faSHans Rosenfeld #include <sys/ddi.h> 223c9168faSHans Rosenfeld #include <sys/sunddi.h> 233c9168faSHans Rosenfeld #include <sys/blkdev.h> 243c9168faSHans Rosenfeld #include <sys/taskq_impl.h> 25*5e3243f0SHans Rosenfeld #include <sys/list.h> 263c9168faSHans Rosenfeld 273c9168faSHans Rosenfeld /* 283c9168faSHans Rosenfeld * NVMe driver state 293c9168faSHans Rosenfeld */ 303c9168faSHans Rosenfeld 313c9168faSHans Rosenfeld #ifdef __cplusplus 32ecee5a1fSHans Rosenfeld extern "C" { 333c9168faSHans Rosenfeld #endif 343c9168faSHans Rosenfeld 353c9168faSHans Rosenfeld #define NVME_FMA_INIT 0x1 363c9168faSHans Rosenfeld #define NVME_REGS_MAPPED 0x2 373c9168faSHans Rosenfeld #define NVME_ADMIN_QUEUE 0x4 383c9168faSHans Rosenfeld #define NVME_CTRL_LIMITS 0x8 393c9168faSHans Rosenfeld #define NVME_INTERRUPTS 0x10 403c9168faSHans Rosenfeld 413c9168faSHans Rosenfeld #define NVME_MIN_ADMIN_QUEUE_LEN 16 423c9168faSHans Rosenfeld #define NVME_MIN_IO_QUEUE_LEN 16 433c9168faSHans Rosenfeld #define NVME_DEFAULT_ADMIN_QUEUE_LEN 256 443c9168faSHans Rosenfeld #define NVME_DEFAULT_IO_QUEUE_LEN 1024 453c9168faSHans Rosenfeld #define NVME_DEFAULT_ASYNC_EVENT_LIMIT 10 463c9168faSHans Rosenfeld #define NVME_MIN_ASYNC_EVENT_LIMIT 1 47be0a819dSHans Rosenfeld #define NVME_DEFAULT_MIN_BLOCK_SIZE 512 483c9168faSHans Rosenfeld 493c9168faSHans Rosenfeld 503c9168faSHans Rosenfeld typedef struct nvme nvme_t; 513c9168faSHans Rosenfeld typedef struct nvme_namespace nvme_namespace_t; 52ecee5a1fSHans Rosenfeld typedef struct nvme_minor_state nvme_minor_state_t; 533c9168faSHans Rosenfeld typedef struct nvme_dma nvme_dma_t; 543c9168faSHans Rosenfeld typedef struct nvme_cmd nvme_cmd_t; 553c9168faSHans Rosenfeld typedef struct nvme_qpair nvme_qpair_t; 563c9168faSHans Rosenfeld typedef struct nvme_task_arg nvme_task_arg_t; 573c9168faSHans Rosenfeld 58ecee5a1fSHans Rosenfeld struct nvme_minor_state { 59ecee5a1fSHans Rosenfeld kmutex_t nm_mutex; 60ecee5a1fSHans Rosenfeld boolean_t nm_oexcl; 61ecee5a1fSHans Rosenfeld uint_t nm_ocnt; 62ecee5a1fSHans Rosenfeld }; 63ecee5a1fSHans Rosenfeld 643c9168faSHans Rosenfeld struct nvme_dma { 653c9168faSHans Rosenfeld ddi_dma_handle_t nd_dmah; 663c9168faSHans Rosenfeld ddi_acc_handle_t nd_acch; 673c9168faSHans Rosenfeld ddi_dma_cookie_t nd_cookie; 683c9168faSHans Rosenfeld uint_t nd_ncookie; 693c9168faSHans Rosenfeld caddr_t nd_memp; 703c9168faSHans Rosenfeld size_t nd_len; 71582eef8cSYouzhong Yang boolean_t nd_cached; 723c9168faSHans Rosenfeld }; 733c9168faSHans Rosenfeld 743c9168faSHans Rosenfeld struct nvme_cmd { 75*5e3243f0SHans Rosenfeld struct list_node nc_list; 76*5e3243f0SHans Rosenfeld 773c9168faSHans Rosenfeld nvme_sqe_t nc_sqe; 783c9168faSHans Rosenfeld nvme_cqe_t nc_cqe; 793c9168faSHans Rosenfeld 803c9168faSHans Rosenfeld void (*nc_callback)(void *); 813c9168faSHans Rosenfeld bd_xfer_t *nc_xfer; 823c9168faSHans Rosenfeld boolean_t nc_completed; 83ecee5a1fSHans Rosenfeld boolean_t nc_dontpanic; 843c9168faSHans Rosenfeld uint16_t nc_sqid; 853c9168faSHans Rosenfeld 863c9168faSHans Rosenfeld nvme_dma_t *nc_dma; 873c9168faSHans Rosenfeld 883c9168faSHans Rosenfeld kmutex_t nc_mutex; 893c9168faSHans Rosenfeld kcondvar_t nc_cv; 903c9168faSHans Rosenfeld 913c9168faSHans Rosenfeld taskq_ent_t nc_tqent; 923c9168faSHans Rosenfeld nvme_t *nc_nvme; 933c9168faSHans Rosenfeld }; 943c9168faSHans Rosenfeld 953c9168faSHans Rosenfeld struct nvme_qpair { 963c9168faSHans Rosenfeld size_t nq_nentry; 973c9168faSHans Rosenfeld 983c9168faSHans Rosenfeld nvme_dma_t *nq_sqdma; 993c9168faSHans Rosenfeld nvme_sqe_t *nq_sq; 1003c9168faSHans Rosenfeld uint_t nq_sqhead; 1013c9168faSHans Rosenfeld uint_t nq_sqtail; 1023c9168faSHans Rosenfeld uintptr_t nq_sqtdbl; 1033c9168faSHans Rosenfeld 1043c9168faSHans Rosenfeld nvme_dma_t *nq_cqdma; 1053c9168faSHans Rosenfeld nvme_cqe_t *nq_cq; 1063c9168faSHans Rosenfeld uint_t nq_cqhead; 1073c9168faSHans Rosenfeld uint_t nq_cqtail; 1083c9168faSHans Rosenfeld uintptr_t nq_cqhdbl; 1093c9168faSHans Rosenfeld 1103c9168faSHans Rosenfeld nvme_cmd_t **nq_cmd; 1113c9168faSHans Rosenfeld uint16_t nq_next_cmd; 1123c9168faSHans Rosenfeld uint_t nq_active_cmds; 1133c9168faSHans Rosenfeld int nq_phase; 1143c9168faSHans Rosenfeld 1153c9168faSHans Rosenfeld kmutex_t nq_mutex; 116adec8d5dSHans Rosenfeld ksema_t nq_sema; 1173c9168faSHans Rosenfeld }; 1183c9168faSHans Rosenfeld 1193c9168faSHans Rosenfeld struct nvme { 1203c9168faSHans Rosenfeld dev_info_t *n_dip; 1213c9168faSHans Rosenfeld int n_progress; 1223c9168faSHans Rosenfeld 1233c9168faSHans Rosenfeld caddr_t n_regs; 1243c9168faSHans Rosenfeld ddi_acc_handle_t n_regh; 1253c9168faSHans Rosenfeld 1263c9168faSHans Rosenfeld kmem_cache_t *n_cmd_cache; 127582eef8cSYouzhong Yang kmem_cache_t *n_prp_cache; 1283c9168faSHans Rosenfeld 1293c9168faSHans Rosenfeld size_t n_inth_sz; 1303c9168faSHans Rosenfeld ddi_intr_handle_t *n_inth; 1313c9168faSHans Rosenfeld int n_intr_cnt; 1323c9168faSHans Rosenfeld uint_t n_intr_pri; 1333c9168faSHans Rosenfeld int n_intr_cap; 1343c9168faSHans Rosenfeld int n_intr_type; 1353c9168faSHans Rosenfeld int n_intr_types; 1363c9168faSHans Rosenfeld 137510a6847SHans Rosenfeld char *n_product; 138510a6847SHans Rosenfeld char *n_vendor; 139510a6847SHans Rosenfeld 140b6fef107SHans Rosenfeld nvme_version_t n_version; 1413c9168faSHans Rosenfeld boolean_t n_dead; 1423c9168faSHans Rosenfeld boolean_t n_strict_version; 1433c9168faSHans Rosenfeld boolean_t n_ignore_unknown_vendor_status; 1443c9168faSHans Rosenfeld uint32_t n_admin_queue_len; 1453c9168faSHans Rosenfeld uint32_t n_io_queue_len; 1463c9168faSHans Rosenfeld uint16_t n_async_event_limit; 147be0a819dSHans Rosenfeld uint_t n_min_block_size; 1483c9168faSHans Rosenfeld uint16_t n_abort_command_limit; 1493c9168faSHans Rosenfeld uint64_t n_max_data_transfer_size; 150998a9ab1SHans Rosenfeld boolean_t n_write_cache_present; 151998a9ab1SHans Rosenfeld boolean_t n_write_cache_enabled; 1523c9168faSHans Rosenfeld int n_error_log_len; 153ecee5a1fSHans Rosenfeld boolean_t n_lba_range_supported; 154ecee5a1fSHans Rosenfeld boolean_t n_auto_pst_supported; 1553c9168faSHans Rosenfeld 1563c9168faSHans Rosenfeld int n_nssr_supported; 1573c9168faSHans Rosenfeld int n_doorbell_stride; 1583c9168faSHans Rosenfeld int n_timeout; 1593c9168faSHans Rosenfeld int n_arbitration_mechanisms; 1603c9168faSHans Rosenfeld int n_cont_queues_reqd; 1613c9168faSHans Rosenfeld int n_max_queue_entries; 1623c9168faSHans Rosenfeld int n_pageshift; 1633c9168faSHans Rosenfeld int n_pagesize; 1643c9168faSHans Rosenfeld 1653c9168faSHans Rosenfeld int n_namespace_count; 166*5e3243f0SHans Rosenfeld uint16_t n_ioq_count; 1673c9168faSHans Rosenfeld 1683c9168faSHans Rosenfeld nvme_identify_ctrl_t *n_idctl; 1693c9168faSHans Rosenfeld 1703c9168faSHans Rosenfeld nvme_qpair_t *n_adminq; 1713c9168faSHans Rosenfeld nvme_qpair_t **n_ioq; 1723c9168faSHans Rosenfeld 1733c9168faSHans Rosenfeld nvme_namespace_t *n_ns; 1743c9168faSHans Rosenfeld 1753c9168faSHans Rosenfeld ddi_dma_attr_t n_queue_dma_attr; 1763c9168faSHans Rosenfeld ddi_dma_attr_t n_prp_dma_attr; 1773c9168faSHans Rosenfeld ddi_dma_attr_t n_sgl_dma_attr; 1783c9168faSHans Rosenfeld ddi_device_acc_attr_t n_reg_acc_attr; 1793c9168faSHans Rosenfeld ddi_iblock_cookie_t n_fm_ibc; 1803c9168faSHans Rosenfeld int n_fm_cap; 1813c9168faSHans Rosenfeld 1823c9168faSHans Rosenfeld ksema_t n_abort_sema; 1833c9168faSHans Rosenfeld 1843c9168faSHans Rosenfeld ddi_taskq_t *n_cmd_taskq; 1853c9168faSHans Rosenfeld 186ecee5a1fSHans Rosenfeld /* state for devctl minor node */ 187ecee5a1fSHans Rosenfeld nvme_minor_state_t n_minor; 1883c9168faSHans Rosenfeld 1893c9168faSHans Rosenfeld /* errors detected by driver */ 1903c9168faSHans Rosenfeld uint32_t n_dma_bind_err; 1913c9168faSHans Rosenfeld uint32_t n_abort_failed; 1923c9168faSHans Rosenfeld uint32_t n_cmd_timeout; 1933c9168faSHans Rosenfeld uint32_t n_cmd_aborted; 1943c9168faSHans Rosenfeld uint32_t n_wrong_logpage; 1953c9168faSHans Rosenfeld uint32_t n_unknown_logpage; 1963c9168faSHans Rosenfeld uint32_t n_too_many_cookies; 1973c9168faSHans Rosenfeld 1983c9168faSHans Rosenfeld /* errors detected by hardware */ 1993c9168faSHans Rosenfeld uint32_t n_data_xfr_err; 2003c9168faSHans Rosenfeld uint32_t n_internal_err; 2013c9168faSHans Rosenfeld uint32_t n_abort_rq_err; 2023c9168faSHans Rosenfeld uint32_t n_abort_sq_del; 2033c9168faSHans Rosenfeld uint32_t n_nvm_cap_exc; 2043c9168faSHans Rosenfeld uint32_t n_nvm_ns_notrdy; 2053c9168faSHans Rosenfeld uint32_t n_inv_cq_err; 2063c9168faSHans Rosenfeld uint32_t n_inv_qid_err; 2073c9168faSHans Rosenfeld uint32_t n_max_qsz_exc; 2083c9168faSHans Rosenfeld uint32_t n_inv_int_vect; 2093c9168faSHans Rosenfeld uint32_t n_inv_log_page; 2103c9168faSHans Rosenfeld uint32_t n_inv_format; 2113c9168faSHans Rosenfeld uint32_t n_inv_q_del; 2123c9168faSHans Rosenfeld uint32_t n_cnfl_attr; 2133c9168faSHans Rosenfeld uint32_t n_inv_prot; 2143c9168faSHans Rosenfeld uint32_t n_readonly; 2153c9168faSHans Rosenfeld 2163c9168faSHans Rosenfeld /* errors reported by asynchronous events */ 2173c9168faSHans Rosenfeld uint32_t n_diagfail_event; 2183c9168faSHans Rosenfeld uint32_t n_persistent_event; 2193c9168faSHans Rosenfeld uint32_t n_transient_event; 2203c9168faSHans Rosenfeld uint32_t n_fw_load_event; 2213c9168faSHans Rosenfeld uint32_t n_reliability_event; 2223c9168faSHans Rosenfeld uint32_t n_temperature_event; 2233c9168faSHans Rosenfeld uint32_t n_spare_event; 2243c9168faSHans Rosenfeld uint32_t n_vendor_event; 2253c9168faSHans Rosenfeld uint32_t n_unknown_event; 2263c9168faSHans Rosenfeld 2273c9168faSHans Rosenfeld }; 2283c9168faSHans Rosenfeld 2293c9168faSHans Rosenfeld struct nvme_namespace { 2303c9168faSHans Rosenfeld nvme_t *ns_nvme; 231b6fef107SHans Rosenfeld uint8_t ns_eui64[8]; 232ecee5a1fSHans Rosenfeld char ns_name[17]; 233b6fef107SHans Rosenfeld 2343c9168faSHans Rosenfeld bd_handle_t ns_bd_hdl; 2353c9168faSHans Rosenfeld 2363c9168faSHans Rosenfeld uint32_t ns_id; 2373c9168faSHans Rosenfeld size_t ns_block_count; 2383c9168faSHans Rosenfeld size_t ns_block_size; 2393c9168faSHans Rosenfeld size_t ns_best_block_size; 2403c9168faSHans Rosenfeld 2413c9168faSHans Rosenfeld boolean_t ns_ignore; 2423c9168faSHans Rosenfeld 2433c9168faSHans Rosenfeld nvme_identify_nsid_t *ns_idns; 2443c9168faSHans Rosenfeld 245ecee5a1fSHans Rosenfeld /* state for attachment point minor node */ 246ecee5a1fSHans Rosenfeld nvme_minor_state_t ns_minor; 247ecee5a1fSHans Rosenfeld 2483c9168faSHans Rosenfeld /* 249b6fef107SHans Rosenfeld * If a namespace has no EUI64, we create a devid in 250b6fef107SHans Rosenfeld * nvme_prepare_devid(). 2513c9168faSHans Rosenfeld */ 252b6fef107SHans Rosenfeld char *ns_devid; 2533c9168faSHans Rosenfeld }; 2543c9168faSHans Rosenfeld 2553c9168faSHans Rosenfeld struct nvme_task_arg { 2563c9168faSHans Rosenfeld nvme_t *nt_nvme; 2573c9168faSHans Rosenfeld nvme_cmd_t *nt_cmd; 2583c9168faSHans Rosenfeld }; 2593c9168faSHans Rosenfeld 260ecee5a1fSHans Rosenfeld 2613c9168faSHans Rosenfeld #ifdef __cplusplus 262ecee5a1fSHans Rosenfeld } 2633c9168faSHans Rosenfeld #endif 2643c9168faSHans Rosenfeld 2653c9168faSHans Rosenfeld #endif /* _NVME_VAR_H */ 266