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