xref: /freebsd/sys/dev/nvmf/controller/nvmft_var.h (revision 8aac90f18aef7c9eea906c3ff9a001ca7b94f375)
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 
114 /* nvmft_controller.c */
115 void	nvmft_controller_error(struct nvmft_controller *ctrlr,
116     struct nvmft_qpair *qp, int error);
117 void	nvmft_controller_lun_changed(struct nvmft_controller *ctrlr,
118     int lun_id);
119 void	nvmft_handle_admin_command(struct nvmft_controller *ctrlr,
120     struct nvmf_capsule *nc);
121 void	nvmft_handle_io_command(struct nvmft_qpair *qp, uint16_t qid,
122     struct nvmf_capsule *nc);
123 int	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);
127 int	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);
131 int	nvmft_printf(struct nvmft_controller *ctrlr, const char *fmt, ...)
132     __printflike(2, 3);
133 
134 /* nvmft_qpair.c */
135 struct nvmft_qpair *nvmft_qpair_init(enum nvmf_trtype trtype,
136     const struct nvmf_handoff_qpair_params *handoff, uint16_t qid,
137     const char *name);
138 void	nvmft_qpair_shutdown(struct nvmft_qpair *qp);
139 void	nvmft_qpair_destroy(struct nvmft_qpair *qp);
140 struct nvmft_controller *nvmft_qpair_ctrlr(struct nvmft_qpair *qp);
141 uint16_t nvmft_qpair_id(struct nvmft_qpair *qp);
142 const char *nvmft_qpair_name(struct nvmft_qpair *qp);
143 void	nvmft_command_completed(struct nvmft_qpair *qp,
144     struct nvmf_capsule *nc);
145 int	nvmft_send_response(struct nvmft_qpair *qp, const void *cqe);
146 void	nvmft_init_cqe(void *cqe, struct nvmf_capsule *nc, uint16_t status);
147 int	nvmft_send_error(struct nvmft_qpair *qp, struct nvmf_capsule *nc,
148     uint8_t sc_type, uint8_t sc_status);
149 int	nvmft_send_generic_error(struct nvmft_qpair *qp,
150     struct nvmf_capsule *nc, uint8_t sc_status);
151 int	nvmft_send_success(struct nvmft_qpair *qp,
152     struct nvmf_capsule *nc);
153 void	nvmft_connect_error(struct nvmft_qpair *qp,
154     const struct nvmf_fabric_connect_cmd *cmd, uint8_t sc_type,
155     uint8_t sc_status);
156 void	nvmft_connect_invalid_parameters(struct nvmft_qpair *qp,
157     const struct nvmf_fabric_connect_cmd *cmd, bool data, uint16_t offset);
158 int	nvmft_finish_accept(struct nvmft_qpair *qp,
159     const struct nvmf_fabric_connect_cmd *cmd, struct nvmft_controller *ctrlr);
160 
161 static __inline void
162 nvmft_port_ref(struct nvmft_port *np)
163 {
164 	refcount_acquire(&np->refs);
165 }
166 
167 static __inline void
168 nvmft_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