xref: /freebsd/sys/dev/nvmf/nvmf_transport_internal.h (revision 7d0873ebb83b19ba1e8a89e679470d885efe12e3)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2022-2024 Chelsio Communications, Inc.
5  * Written by: John Baldwin <jhb@FreeBSD.org>
6  */
7 
8 #ifndef __NVMF_TRANSPORT_INTERNAL_H__
9 #define	__NVMF_TRANSPORT_INTERNAL_H__
10 
11 #include <sys/_nv.h>
12 #include <sys/memdesc.h>
13 
14 /*
15  * Interface between the transport-independent APIs in
16  * nvmf_transport.c and individual transports.
17  */
18 
19 struct module;
20 struct nvmf_io_request;
21 
22 struct nvmf_transport_ops {
23 	/* Queue pair management. */
24 	struct nvmf_qpair *(*allocate_qpair)(bool controller,
25 	    const nvlist_t *nvl);
26 	void (*free_qpair)(struct nvmf_qpair *qp);
27 
28 	/* Capsule operations. */
29 	struct nvmf_capsule *(*allocate_capsule)(struct nvmf_qpair *qp,
30 	    int how);
31 	void (*free_capsule)(struct nvmf_capsule *nc);
32 	int (*transmit_capsule)(struct nvmf_capsule *nc);
33 	uint8_t (*validate_command_capsule)(struct nvmf_capsule *nc);
34 
35 	/* Transferring controller data. */
36 	size_t (*capsule_data_len)(const struct nvmf_capsule *nc);
37 	int (*receive_controller_data)(struct nvmf_capsule *nc,
38 	    uint32_t data_offset, struct nvmf_io_request *io);
39 	u_int (*send_controller_data)(struct nvmf_capsule *nc,
40 	    uint32_t data_offset, struct mbuf *m, size_t len);
41 
42 	enum nvmf_trtype trtype;
43 	int priority;
44 };
45 
46 /* Either an Admin or I/O Submission/Completion Queue pair. */
47 struct nvmf_qpair {
48 	struct nvmf_transport *nq_transport;
49 	struct nvmf_transport_ops *nq_ops;
50 	bool nq_controller;
51 
52 	/* Callback to invoke for a received capsule. */
53 	nvmf_capsule_receive_t *nq_receive;
54 	void *nq_receive_arg;
55 
56 	/* Callback to invoke for an error. */
57 	nvmf_qpair_error_t *nq_error;
58 	void *nq_error_arg;
59 
60 	bool nq_admin;
61 };
62 
63 struct nvmf_io_request {
64 	/*
65 	 * Data buffer contains io_len bytes in the backing store
66 	 * described by mem.
67 	 */
68 	struct memdesc io_mem;
69 	size_t	io_len;
70 	nvmf_io_complete_t *io_complete;
71 	void	*io_complete_arg;
72 };
73 
74 /*
75  * Fabrics Command and Response Capsules.  The Fabrics host
76  * (initiator) and controller (target) drivers work with capsules that
77  * are transmitted and received by a specific transport.
78  */
79 struct nvmf_capsule {
80 	struct nvmf_qpair *nc_qpair;
81 
82 	/* Either a SQE or CQE. */
83 	union {
84 		struct nvme_command nc_sqe;
85 		struct nvme_completion nc_cqe;
86 	};
87 	int	nc_qe_len;
88 
89 	/*
90 	 * Is SQHD in received capsule valid?  False for locally-
91 	 * synthesized responses.
92 	 */
93 	bool	nc_sqhd_valid;
94 
95 	bool	nc_send_data;
96 	struct nvmf_io_request nc_data;
97 };
98 
99 static void __inline
100 nvmf_qpair_error(struct nvmf_qpair *nq, int error)
101 {
102 	nq->nq_error(nq->nq_error_arg, error);
103 }
104 
105 static void __inline
106 nvmf_capsule_received(struct nvmf_qpair *nq, struct nvmf_capsule *nc)
107 {
108 	nq->nq_receive(nq->nq_receive_arg, nc);
109 }
110 
111 static void __inline
112 nvmf_complete_io_request(struct nvmf_io_request *io, size_t xfered, int error)
113 {
114 	io->io_complete(io->io_complete_arg, xfered, error);
115 }
116 
117 int	nvmf_transport_module_handler(struct module *, int, void *);
118 
119 #define	NVMF_TRANSPORT(name, ops)					\
120 static moduledata_t nvmf_transport_##name##_mod = {			\
121 	"nvmf/" #name,							\
122 	nvmf_transport_module_handler,					\
123 	&(ops)								\
124 };									\
125 DECLARE_MODULE(nvmf_transport_##name, nvmf_transport_##name##_mod,	\
126     SI_SUB_DRIVERS, SI_ORDER_ANY);					\
127 MODULE_DEPEND(nvmf_transport_##name, nvmf_transport, 1, 1, 1)
128 
129 #endif /* !__NVMF_TRANSPORT_INTERNAL_H__ */
130