xref: /freebsd/sys/dev/nvmf/host/nvmf_var.h (revision 38e1083940a274783cc9e8ebd845e35df6d0a1ff)
1a1eda741SJohn Baldwin /*-
2a1eda741SJohn Baldwin  * SPDX-License-Identifier: BSD-2-Clause
3a1eda741SJohn Baldwin  *
4a1eda741SJohn Baldwin  * Copyright (c) 2023-2024 Chelsio Communications, Inc.
5a1eda741SJohn Baldwin  * Written by: John Baldwin <jhb@FreeBSD.org>
6a1eda741SJohn Baldwin  */
7a1eda741SJohn Baldwin 
8a1eda741SJohn Baldwin #ifndef __NVMF_VAR_H__
9a1eda741SJohn Baldwin #define	__NVMF_VAR_H__
10a1eda741SJohn Baldwin 
11a1eda741SJohn Baldwin #include <sys/_callout.h>
12f46d4971SJohn Baldwin #include <sys/_eventhandler.h>
13a1eda741SJohn Baldwin #include <sys/_lock.h>
14a1eda741SJohn Baldwin #include <sys/_mutex.h>
15365b89e8SJohn Baldwin //#include <sys/_nv.h>
16a1eda741SJohn Baldwin #include <sys/_sx.h>
17a1eda741SJohn Baldwin #include <sys/_task.h>
183ff90d91SJohn Baldwin #include <sys/smp.h>
19a1eda741SJohn Baldwin #include <sys/queue.h>
20a1eda741SJohn Baldwin #include <dev/nvme/nvme.h>
21a1eda741SJohn Baldwin #include <dev/nvmf/nvmf_transport.h>
22a1eda741SJohn Baldwin 
23a1eda741SJohn Baldwin struct nvmf_aer;
24a1eda741SJohn Baldwin struct nvmf_capsule;
25a1eda741SJohn Baldwin struct nvmf_host_qpair;
26a1eda741SJohn Baldwin struct nvmf_namespace;
27931dd5feSJohn Baldwin struct sysctl_oid_list;
28a1eda741SJohn Baldwin 
29a1eda741SJohn Baldwin typedef void nvmf_request_complete_t(void *, const struct nvme_completion *);
30a1eda741SJohn Baldwin 
31a1eda741SJohn Baldwin struct nvmf_softc {
32a1eda741SJohn Baldwin 	device_t dev;
33a1eda741SJohn Baldwin 
34a1eda741SJohn Baldwin 	struct nvmf_host_qpair *admin;
35a1eda741SJohn Baldwin 	struct nvmf_host_qpair **io;
36a1eda741SJohn Baldwin 	u_int	num_io_queues;
37a1eda741SJohn Baldwin 	enum nvmf_trtype trtype;
38a1eda741SJohn Baldwin 
39a1eda741SJohn Baldwin 	struct cam_sim *sim;
40a1eda741SJohn Baldwin 	struct cam_path *path;
41a1eda741SJohn Baldwin 	struct mtx sim_mtx;
42a1eda741SJohn Baldwin 	bool sim_disconnected;
43f46d4971SJohn Baldwin 	bool sim_shutdown;
44a1eda741SJohn Baldwin 
45a1eda741SJohn Baldwin 	struct nvmf_namespace **ns;
46a1eda741SJohn Baldwin 
47a1eda741SJohn Baldwin 	struct nvme_controller_data *cdata;
48a1eda741SJohn Baldwin 	uint64_t cap;
49a1eda741SJohn Baldwin 	uint32_t vs;
50a1eda741SJohn Baldwin 	u_int max_pending_io;
51a1eda741SJohn Baldwin 	u_long max_xfer_size;
52a1eda741SJohn Baldwin 
53a1eda741SJohn Baldwin 	struct cdev *cdev;
54a1eda741SJohn Baldwin 
55a1eda741SJohn Baldwin 	/*
56a1eda741SJohn Baldwin 	 * Keep Alive support depends on two timers.  The 'tx' timer
57a1eda741SJohn Baldwin 	 * is responsible for sending KeepAlive commands and runs at
58a1eda741SJohn Baldwin 	 * half the timeout interval.  The 'rx' timer is responsible
59a1eda741SJohn Baldwin 	 * for detecting an actual timeout.
60a1eda741SJohn Baldwin 	 *
61a1eda741SJohn Baldwin 	 * For efficient support of TKAS, the host does not reschedule
62a1eda741SJohn Baldwin 	 * these timers every time new commands are scheduled.
63a1eda741SJohn Baldwin 	 * Instead, the host sets the *_traffic flags when commands
64a1eda741SJohn Baldwin 	 * are sent and received.  The timeout handlers check and
65a1eda741SJohn Baldwin 	 * clear these flags.  This does mean it can take up to twice
66a1eda741SJohn Baldwin 	 * the timeout time to detect an AWOL controller.
67a1eda741SJohn Baldwin 	 */
68a1eda741SJohn Baldwin 	bool	ka_traffic;			/* Using TKAS? */
69a1eda741SJohn Baldwin 
70a1eda741SJohn Baldwin 	volatile int ka_active_tx_traffic;
71a1eda741SJohn Baldwin 	struct callout ka_tx_timer;
72a1eda741SJohn Baldwin 	sbintime_t ka_tx_sbt;
73a1eda741SJohn Baldwin 
74a1eda741SJohn Baldwin 	volatile int ka_active_rx_traffic;
75a1eda741SJohn Baldwin 	struct callout ka_rx_timer;
76a1eda741SJohn Baldwin 	sbintime_t ka_rx_sbt;
77a1eda741SJohn Baldwin 
78a1eda741SJohn Baldwin 	struct sx connection_lock;
79a1eda741SJohn Baldwin 	struct task disconnect_task;
80a1eda741SJohn Baldwin 	bool detaching;
81a1eda741SJohn Baldwin 
82a1eda741SJohn Baldwin 	u_int num_aer;
83a1eda741SJohn Baldwin 	struct nvmf_aer *aer;
84f46d4971SJohn Baldwin 
85931dd5feSJohn Baldwin 	struct sysctl_oid_list *ioq_oid_list;
86931dd5feSJohn Baldwin 
878bba2c0fSJohn Baldwin 	nvlist_t *rparams;
888bba2c0fSJohn Baldwin 
89*38e10839SJohn Baldwin 	struct timespec last_disconnect;
90*38e10839SJohn Baldwin 
91f46d4971SJohn Baldwin 	eventhandler_tag shutdown_pre_sync_eh;
92f46d4971SJohn Baldwin 	eventhandler_tag shutdown_post_sync_eh;
93a1eda741SJohn Baldwin };
94a1eda741SJohn Baldwin 
95a1eda741SJohn Baldwin struct nvmf_request {
96a1eda741SJohn Baldwin 	struct nvmf_host_qpair *qp;
97a1eda741SJohn Baldwin 	struct nvmf_capsule *nc;
98a1eda741SJohn Baldwin 	nvmf_request_complete_t *cb;
99a1eda741SJohn Baldwin 	void	*cb_arg;
100a1eda741SJohn Baldwin 	bool	aer;
101a1eda741SJohn Baldwin 
102a1eda741SJohn Baldwin 	STAILQ_ENTRY(nvmf_request) link;
103a1eda741SJohn Baldwin };
104a1eda741SJohn Baldwin 
105a1eda741SJohn Baldwin struct nvmf_completion_status {
106a1eda741SJohn Baldwin 	struct nvme_completion cqe;
107a1eda741SJohn Baldwin 	bool	done;
108a1eda741SJohn Baldwin 	bool	io_done;
109a1eda741SJohn Baldwin 	int	io_error;
110a1eda741SJohn Baldwin };
111a1eda741SJohn Baldwin 
112a1eda741SJohn Baldwin static __inline struct nvmf_host_qpair *
nvmf_select_io_queue(struct nvmf_softc * sc)113a1eda741SJohn Baldwin nvmf_select_io_queue(struct nvmf_softc *sc)
114a1eda741SJohn Baldwin {
1153ff90d91SJohn Baldwin 	u_int idx = curcpu * sc->num_io_queues / (mp_maxid + 1);
1163ff90d91SJohn Baldwin 	return (sc->io[idx]);
117a1eda741SJohn Baldwin }
118a1eda741SJohn Baldwin 
119a1eda741SJohn Baldwin static __inline bool
nvmf_cqe_aborted(const struct nvme_completion * cqe)120a1eda741SJohn Baldwin nvmf_cqe_aborted(const struct nvme_completion *cqe)
121a1eda741SJohn Baldwin {
122a1eda741SJohn Baldwin 	uint16_t status;
123a1eda741SJohn Baldwin 
124a1eda741SJohn Baldwin 	status = le16toh(cqe->status);
125a1eda741SJohn Baldwin 	return (NVME_STATUS_GET_SCT(status) == NVME_SCT_PATH_RELATED &&
126a1eda741SJohn Baldwin 	    NVME_STATUS_GET_SC(status) == NVME_SC_COMMAND_ABORTED_BY_HOST);
127a1eda741SJohn Baldwin }
128a1eda741SJohn Baldwin 
129a1eda741SJohn Baldwin static __inline void
nvmf_status_init(struct nvmf_completion_status * status)130a1eda741SJohn Baldwin nvmf_status_init(struct nvmf_completion_status *status)
131a1eda741SJohn Baldwin {
132a1eda741SJohn Baldwin 	status->done = false;
133a1eda741SJohn Baldwin 	status->io_done = true;
134a1eda741SJohn Baldwin 	status->io_error = 0;
135a1eda741SJohn Baldwin }
136a1eda741SJohn Baldwin 
137a1eda741SJohn Baldwin static __inline void
nvmf_status_wait_io(struct nvmf_completion_status * status)138a1eda741SJohn Baldwin nvmf_status_wait_io(struct nvmf_completion_status *status)
139a1eda741SJohn Baldwin {
140a1eda741SJohn Baldwin 	status->io_done = false;
141a1eda741SJohn Baldwin }
142a1eda741SJohn Baldwin 
143a1eda741SJohn Baldwin #ifdef DRIVER_MODULE
144a1eda741SJohn Baldwin extern driver_t nvme_nvmf_driver;
145a1eda741SJohn Baldwin #endif
146a1eda741SJohn Baldwin 
147a1eda741SJohn Baldwin #ifdef MALLOC_DECLARE
148a1eda741SJohn Baldwin MALLOC_DECLARE(M_NVMF);
149a1eda741SJohn Baldwin #endif
150a1eda741SJohn Baldwin 
151aacaeeeeSJohn Baldwin /* If true, I/O requests will fail while the host is disconnected. */
152aacaeeeeSJohn Baldwin extern bool nvmf_fail_disconnect;
153aacaeeeeSJohn Baldwin 
154a1eda741SJohn Baldwin /* nvmf.c */
155a1eda741SJohn Baldwin void	nvmf_complete(void *arg, const struct nvme_completion *cqe);
156a1eda741SJohn Baldwin void	nvmf_io_complete(void *arg, size_t xfered, int error);
157a1eda741SJohn Baldwin void	nvmf_wait_for_reply(struct nvmf_completion_status *status);
158365b89e8SJohn Baldwin int	nvmf_copyin_handoff(const struct nvmf_ioc_nv *nv, nvlist_t **nvlp);
159a1eda741SJohn Baldwin void	nvmf_disconnect(struct nvmf_softc *sc);
160a1eda741SJohn Baldwin void	nvmf_rescan_ns(struct nvmf_softc *sc, uint32_t nsid);
161f6d434f1SJohn Baldwin void	nvmf_rescan_all_ns(struct nvmf_softc *sc);
162a1eda741SJohn Baldwin int	nvmf_passthrough_cmd(struct nvmf_softc *sc, struct nvme_pt_command *pt,
163a1eda741SJohn Baldwin     bool admin);
164a1eda741SJohn Baldwin 
165a1eda741SJohn Baldwin /* nvmf_aer.c */
166a1eda741SJohn Baldwin void	nvmf_init_aer(struct nvmf_softc *sc);
167a1eda741SJohn Baldwin int	nvmf_start_aer(struct nvmf_softc *sc);
168a1eda741SJohn Baldwin void	nvmf_destroy_aer(struct nvmf_softc *sc);
169a1eda741SJohn Baldwin 
170a1eda741SJohn Baldwin /* nvmf_cmd.c */
171a1eda741SJohn Baldwin bool	nvmf_cmd_get_property(struct nvmf_softc *sc, uint32_t offset,
172a1eda741SJohn Baldwin     uint8_t size, nvmf_request_complete_t *cb, void *cb_arg, int how);
173a1eda741SJohn Baldwin bool	nvmf_cmd_set_property(struct nvmf_softc *sc, uint32_t offset,
174a1eda741SJohn Baldwin     uint8_t size, uint64_t value, nvmf_request_complete_t *cb, void *cb_arg,
175a1eda741SJohn Baldwin     int how);
176a1eda741SJohn Baldwin bool	nvmf_cmd_keep_alive(struct nvmf_softc *sc, nvmf_request_complete_t *cb,
177a1eda741SJohn Baldwin     void *cb_arg, int how);
178a1eda741SJohn Baldwin bool	nvmf_cmd_identify_active_namespaces(struct nvmf_softc *sc, uint32_t id,
179a1eda741SJohn Baldwin     struct nvme_ns_list *nslist, nvmf_request_complete_t *req_cb,
180a1eda741SJohn Baldwin     void *req_cb_arg, nvmf_io_complete_t *io_cb, void *io_cb_arg, int how);
181a1eda741SJohn Baldwin bool	nvmf_cmd_identify_namespace(struct nvmf_softc *sc, uint32_t id,
182a1eda741SJohn Baldwin     struct nvme_namespace_data *nsdata, nvmf_request_complete_t *req_cb,
183a1eda741SJohn Baldwin     void *req_cb_arg, nvmf_io_complete_t *io_cb, void *io_cb_arg, int how);
184a1eda741SJohn Baldwin bool	nvmf_cmd_get_log_page(struct nvmf_softc *sc, uint32_t nsid, uint8_t lid,
185a1eda741SJohn Baldwin     uint64_t offset, void *buf, size_t len, nvmf_request_complete_t *req_cb,
186a1eda741SJohn Baldwin     void *req_cb_arg, nvmf_io_complete_t *io_cb, void *io_cb_arg, int how);
187a1eda741SJohn Baldwin 
188a1eda741SJohn Baldwin /* nvmf_ctldev.c */
189a1eda741SJohn Baldwin int	nvmf_ctl_load(void);
190a1eda741SJohn Baldwin void	nvmf_ctl_unload(void);
191a1eda741SJohn Baldwin 
192a1eda741SJohn Baldwin /* nvmf_ns.c */
193a1eda741SJohn Baldwin struct nvmf_namespace *nvmf_init_ns(struct nvmf_softc *sc, uint32_t id,
194bed59babSJohn Baldwin     const struct nvme_namespace_data *data);
195a1eda741SJohn Baldwin void	nvmf_disconnect_ns(struct nvmf_namespace *ns);
196a1eda741SJohn Baldwin void	nvmf_reconnect_ns(struct nvmf_namespace *ns);
197f46d4971SJohn Baldwin void	nvmf_shutdown_ns(struct nvmf_namespace *ns);
198a1eda741SJohn Baldwin void	nvmf_destroy_ns(struct nvmf_namespace *ns);
199a1eda741SJohn Baldwin bool	nvmf_update_ns(struct nvmf_namespace *ns,
200bed59babSJohn Baldwin     const struct nvme_namespace_data *data);
201a1eda741SJohn Baldwin 
202a1eda741SJohn Baldwin /* nvmf_qpair.c */
203a1eda741SJohn Baldwin struct nvmf_host_qpair *nvmf_init_qp(struct nvmf_softc *sc,
204365b89e8SJohn Baldwin     enum nvmf_trtype trtype, const nvlist_t *nvl, const char *name, u_int qid);
205a1eda741SJohn Baldwin void	nvmf_shutdown_qp(struct nvmf_host_qpair *qp);
206a1eda741SJohn Baldwin void	nvmf_destroy_qp(struct nvmf_host_qpair *qp);
207a1eda741SJohn Baldwin struct nvmf_request *nvmf_allocate_request(struct nvmf_host_qpair *qp,
208a1eda741SJohn Baldwin     void *sqe, nvmf_request_complete_t *cb, void *cb_arg, int how);
209a1eda741SJohn Baldwin void	nvmf_submit_request(struct nvmf_request *req);
210a1eda741SJohn Baldwin void	nvmf_free_request(struct nvmf_request *req);
211a1eda741SJohn Baldwin 
212a1eda741SJohn Baldwin /* nvmf_sim.c */
213a1eda741SJohn Baldwin int	nvmf_init_sim(struct nvmf_softc *sc);
214a1eda741SJohn Baldwin void	nvmf_disconnect_sim(struct nvmf_softc *sc);
215a1eda741SJohn Baldwin void	nvmf_reconnect_sim(struct nvmf_softc *sc);
216f46d4971SJohn Baldwin void	nvmf_shutdown_sim(struct nvmf_softc *sc);
217a1eda741SJohn Baldwin void	nvmf_destroy_sim(struct nvmf_softc *sc);
218a1eda741SJohn Baldwin void	nvmf_sim_rescan_ns(struct nvmf_softc *sc, uint32_t id);
219a1eda741SJohn Baldwin 
220a1eda741SJohn Baldwin #endif /* !__NVMF_VAR_H__ */
221