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 21struct nvmf_capsule; 22struct nvmft_controller; 23struct nvmft_qpair; 24 25#define NVMFT_NUM_AER 16 26 27struct 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 46struct nvmft_io_qpair { 47 struct nvmft_qpair *qp; 48 49 bool shutdown; 50}; 51 52struct 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 104MALLOC_DECLARE(M_NVMFT); 105 106/* ctl_frontend_nvmf.c */ 107void nvmft_port_free(struct nvmft_port *np); 108void nvmft_populate_active_nslist(struct nvmft_port *np, uint32_t nsid, 109 struct nvme_ns_list *nslist); 110void nvmft_dispatch_command(struct nvmft_qpair *qp, 111 struct nvmf_capsule *nc, bool admin); 112void nvmft_terminate_commands(struct nvmft_controller *ctrlr); 113 114/* nvmft_controller.c */ 115void nvmft_controller_error(struct nvmft_controller *ctrlr, 116 struct nvmft_qpair *qp, int error); 117void nvmft_controller_lun_changed(struct nvmft_controller *ctrlr, 118 int lun_id); 119void nvmft_handle_admin_command(struct nvmft_controller *ctrlr, 120 struct nvmf_capsule *nc); 121void nvmft_handle_io_command(struct nvmft_qpair *qp, uint16_t qid, 122 struct nvmf_capsule *nc); 123int nvmft_handoff_admin_queue(struct nvmft_port *np, 124 const struct nvmf_handoff_controller_qpair *handoff, 125 const struct nvmf_fabric_connect_cmd *cmd, 126 const struct nvmf_fabric_connect_data *data); 127int nvmft_handoff_io_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); 131int nvmft_printf(struct nvmft_controller *ctrlr, const char *fmt, ...) 132 __printflike(2, 3); 133 134/* nvmft_qpair.c */ 135struct nvmft_qpair *nvmft_qpair_init(enum nvmf_trtype trtype, 136 const struct nvmf_handoff_qpair_params *handoff, uint16_t qid, 137 const char *name); 138void nvmft_qpair_shutdown(struct nvmft_qpair *qp); 139void nvmft_qpair_destroy(struct nvmft_qpair *qp); 140struct nvmft_controller *nvmft_qpair_ctrlr(struct nvmft_qpair *qp); 141uint16_t nvmft_qpair_id(struct nvmft_qpair *qp); 142const char *nvmft_qpair_name(struct nvmft_qpair *qp); 143void nvmft_command_completed(struct nvmft_qpair *qp, 144 struct nvmf_capsule *nc); 145int nvmft_send_response(struct nvmft_qpair *qp, const void *cqe); 146void nvmft_init_cqe(void *cqe, struct nvmf_capsule *nc, uint16_t status); 147int nvmft_send_error(struct nvmft_qpair *qp, struct nvmf_capsule *nc, 148 uint8_t sc_type, uint8_t sc_status); 149int nvmft_send_generic_error(struct nvmft_qpair *qp, 150 struct nvmf_capsule *nc, uint8_t sc_status); 151int nvmft_send_success(struct nvmft_qpair *qp, 152 struct nvmf_capsule *nc); 153void nvmft_connect_error(struct nvmft_qpair *qp, 154 const struct nvmf_fabric_connect_cmd *cmd, uint8_t sc_type, 155 uint8_t sc_status); 156void nvmft_connect_invalid_parameters(struct nvmft_qpair *qp, 157 const struct nvmf_fabric_connect_cmd *cmd, bool data, uint16_t offset); 158int nvmft_finish_accept(struct nvmft_qpair *qp, 159 const struct nvmf_fabric_connect_cmd *cmd, struct nvmft_controller *ctrlr); 160 161static __inline void 162nvmft_port_ref(struct nvmft_port *np) 163{ 164 refcount_acquire(&np->refs); 165} 166 167static __inline void 168nvmft_port_rele(struct nvmft_port *np) 169{ 170 if (refcount_release(&np->refs)) 171 nvmft_port_free(np); 172} 173 174#endif /* !__NVMFT_VAR_H__ */ 175