1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2023-2024 Chelsio Communications, Inc. 5 * Written by: John Baldwin <jhb@FreeBSD.org> 6 */ 7 8 #ifndef __NVMFT_VAR_H__ 9 #define __NVMFT_VAR_H__ 10 11 #include <sys/_callout.h> 12 #include <sys/refcount.h> 13 #include <sys/taskqueue.h> 14 15 #include <dev/nvmf/nvmf_proto.h> 16 17 #include <cam/ctl/ctl.h> 18 #include <cam/ctl/ctl_io.h> 19 #include <cam/ctl/ctl_frontend.h> 20 21 struct nvmf_capsule; 22 struct nvmft_controller; 23 struct nvmft_qpair; 24 25 #define NVMFT_NUM_AER 16 26 27 struct nvmft_port { 28 TAILQ_ENTRY(nvmft_port) link; 29 u_int refs; 30 struct ctl_port port; 31 struct nvme_controller_data cdata; 32 struct nvme_firmware_page fp; 33 uint64_t cap; 34 uint32_t max_io_qsize; 35 bool online; 36 37 struct sx lock; 38 39 struct unrhdr *ids; 40 TAILQ_HEAD(, nvmft_controller) controllers; 41 42 uint32_t *active_ns; 43 u_int num_ns; 44 }; 45 46 struct nvmft_io_qpair { 47 struct nvmft_qpair *qp; 48 49 bool shutdown; 50 }; 51 52 struct nvmft_controller { 53 struct nvmft_qpair *admin; 54 struct nvmft_io_qpair *io_qpairs; 55 u_int num_io_queues; 56 bool shutdown; 57 bool admin_closed; 58 uint16_t cntlid; 59 uint32_t cc; 60 uint32_t csts; 61 62 struct nvmft_port *np; 63 struct mtx lock; 64 65 struct nvme_controller_data cdata; 66 struct nvme_health_information_page hip; 67 sbintime_t create_time; 68 sbintime_t start_busy; 69 sbintime_t busy_total; 70 uint16_t partial_dur; 71 uint16_t partial_duw; 72 73 uint8_t hostid[16]; 74 uint8_t hostnqn[NVME_NQN_FIELD_SIZE]; 75 u_int trtype; 76 77 TAILQ_ENTRY(nvmft_controller) link; 78 79 /* 80 * Each queue can have at most UINT16_MAX commands, so the total 81 * across all queues will fit in a uint32_t. 82 */ 83 uint32_t pending_commands; 84 85 volatile int ka_active_traffic; 86 struct callout ka_timer; 87 sbintime_t ka_sbt; 88 89 /* AER fields. */ 90 uint32_t aer_mask; 91 uint16_t aer_cids[NVMFT_NUM_AER]; 92 uint8_t aer_pending; 93 uint8_t aer_cidx; 94 uint8_t aer_pidx; 95 96 /* Changed namespace IDs. */ 97 struct nvme_ns_list *changed_ns; 98 bool changed_ns_reported; 99 100 struct task shutdown_task; 101 struct timeout_task terminate_task; 102 }; 103 104 MALLOC_DECLARE(M_NVMFT); 105 106 /* ctl_frontend_nvmf.c */ 107 void nvmft_port_free(struct nvmft_port *np); 108 void nvmft_populate_active_nslist(struct nvmft_port *np, uint32_t nsid, 109 struct nvme_ns_list *nslist); 110 void nvmft_dispatch_command(struct nvmft_qpair *qp, 111 struct nvmf_capsule *nc, bool admin); 112 void nvmft_terminate_commands(struct nvmft_controller *ctrlr); 113 void nvmft_abort_datamove(union ctl_io *io); 114 void nvmft_handle_datamove(union ctl_io *io); 115 void nvmft_drain_task(struct task *task); 116 void nvmft_enqueue_task(struct task *task); 117 118 /* nvmft_controller.c */ 119 void nvmft_controller_error(struct nvmft_controller *ctrlr, 120 struct nvmft_qpair *qp, int error); 121 void nvmft_controller_lun_changed(struct nvmft_controller *ctrlr, 122 int lun_id); 123 void nvmft_handle_admin_command(struct nvmft_controller *ctrlr, 124 struct nvmf_capsule *nc); 125 void nvmft_handle_io_command(struct nvmft_qpair *qp, uint16_t qid, 126 struct nvmf_capsule *nc); 127 int nvmft_handoff_admin_queue(struct nvmft_port *np, 128 const struct nvmf_handoff_controller_qpair *handoff, 129 const struct nvmf_fabric_connect_cmd *cmd, 130 const struct nvmf_fabric_connect_data *data); 131 int nvmft_handoff_io_queue(struct nvmft_port *np, 132 const struct nvmf_handoff_controller_qpair *handoff, 133 const struct nvmf_fabric_connect_cmd *cmd, 134 const struct nvmf_fabric_connect_data *data); 135 int nvmft_printf(struct nvmft_controller *ctrlr, const char *fmt, ...) 136 __printflike(2, 3); 137 138 /* nvmft_qpair.c */ 139 struct nvmft_qpair *nvmft_qpair_init(enum nvmf_trtype trtype, 140 const struct nvmf_handoff_qpair_params *handoff, uint16_t qid, 141 const char *name); 142 void nvmft_qpair_shutdown(struct nvmft_qpair *qp); 143 void nvmft_qpair_destroy(struct nvmft_qpair *qp); 144 struct nvmft_controller *nvmft_qpair_ctrlr(struct nvmft_qpair *qp); 145 void nvmft_qpair_datamove(struct nvmft_qpair *qp, union ctl_io *io); 146 uint16_t nvmft_qpair_id(struct nvmft_qpair *qp); 147 const char *nvmft_qpair_name(struct nvmft_qpair *qp); 148 void nvmft_command_completed(struct nvmft_qpair *qp, 149 struct nvmf_capsule *nc); 150 int nvmft_send_response(struct nvmft_qpair *qp, const void *cqe); 151 void nvmft_init_cqe(void *cqe, struct nvmf_capsule *nc, uint16_t status); 152 int nvmft_send_error(struct nvmft_qpair *qp, struct nvmf_capsule *nc, 153 uint8_t sc_type, uint8_t sc_status); 154 int nvmft_send_generic_error(struct nvmft_qpair *qp, 155 struct nvmf_capsule *nc, uint8_t sc_status); 156 int nvmft_send_success(struct nvmft_qpair *qp, 157 struct nvmf_capsule *nc); 158 void nvmft_connect_error(struct nvmft_qpair *qp, 159 const struct nvmf_fabric_connect_cmd *cmd, uint8_t sc_type, 160 uint8_t sc_status); 161 void nvmft_connect_invalid_parameters(struct nvmft_qpair *qp, 162 const struct nvmf_fabric_connect_cmd *cmd, bool data, uint16_t offset); 163 int nvmft_finish_accept(struct nvmft_qpair *qp, 164 const struct nvmf_fabric_connect_cmd *cmd, struct nvmft_controller *ctrlr); 165 166 static __inline void 167 nvmft_port_ref(struct nvmft_port *np) 168 { 169 refcount_acquire(&np->refs); 170 } 171 172 static __inline void 173 nvmft_port_rele(struct nvmft_port *np) 174 { 175 if (refcount_release(&np->refs)) 176 nvmft_port_free(np); 177 } 178 179 #endif /* !__NVMFT_VAR_H__ */ 180