xref: /freebsd/sys/dev/nvmf/nvmf_transport.h (revision c1b3c5f5f3fab895df3d2e75ac3edee4e9aa6432)
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_H__
9 #define	__NVMF_TRANSPORT_H__
10 
11 /*
12  * Interface used by the Fabrics host (initiator) and controller
13  * (target) to send and receive capsules and associated data.
14  */
15 
16 #include <sys/_nv.h>
17 #include <sys/sysctl.h>
18 #include <dev/nvmf/nvmf_proto.h>
19 
20 struct mbuf;
21 struct memdesc;
22 struct nvmf_capsule;
23 struct nvmf_connection;
24 struct nvmf_ioc_nv;
25 struct nvmf_qpair;
26 
27 SYSCTL_DECL(_kern_nvmf);
28 
29 /*
30  * Callback to invoke when an error occurs on a qpair.  The last
31  * parameter is an error value.  If the error value is zero, the qpair
32  * has been closed at the transport level rather than a transport
33  * error occuring.
34  */
35 typedef void nvmf_qpair_error_t(void *, int);
36 
37 /* Callback to invoke when a capsule is received. */
38 typedef void nvmf_capsule_receive_t(void *, struct nvmf_capsule *);
39 
40 /*
41  * Callback to invoke when an I/O request has completed.  The second
42  * parameter is the amount of data transferred.  The last parameter is
43  * an error value which is non-zero if the request did not complete
44  * successfully.  A request with an error may complete partially.
45  */
46 typedef void nvmf_io_complete_t(void *, size_t, int);
47 
48 /*
49  * A queue pair represents either an Admin or I/O
50  * submission/completion queue pair.  The params contains negotiated
51  * values passed in from userland.
52  *
53  * Unlike libnvmf in userland, the kernel transport interface does not
54  * have any notion of an association.  Instead, qpairs are
55  * independent.
56  */
57 struct nvmf_qpair *nvmf_allocate_qpair(enum nvmf_trtype trtype,
58     bool controller, const nvlist_t *params,
59     nvmf_qpair_error_t *error_cb, void *error_cb_arg,
60     nvmf_capsule_receive_t *receive_cb, void *receive_cb_arg);
61 void	nvmf_free_qpair(struct nvmf_qpair *qp);
62 
63 /*
64  * Capsules are either commands (host -> controller) or responses
65  * (controller -> host).  A data buffer may be associated with a
66  * command capsule.  Transmitted data is not copied by this API but
67  * instead must be preserved until the completion callback is invoked
68  * to indicate capsule transmission has completed.
69  */
70 struct nvmf_capsule *nvmf_allocate_command(struct nvmf_qpair *qp,
71     const void *sqe, int how);
72 struct nvmf_capsule *nvmf_allocate_response(struct nvmf_qpair *qp,
73     const void *cqe, int how);
74 void	nvmf_free_capsule(struct nvmf_capsule *nc);
75 int	nvmf_capsule_append_data(struct nvmf_capsule *nc,
76     struct memdesc *mem, size_t len, bool send,
77     nvmf_io_complete_t *complete_cb, void *cb_arg);
78 int	nvmf_transmit_capsule(struct nvmf_capsule *nc);
79 void	nvmf_abort_capsule_data(struct nvmf_capsule *nc, int error);
80 void *nvmf_capsule_sqe(struct nvmf_capsule *nc);
81 void *nvmf_capsule_cqe(struct nvmf_capsule *nc);
82 bool	nvmf_sqhd_valid(struct nvmf_capsule *nc);
83 
84 /* Host-specific APIs. */
85 
86 /*
87  * Largest I/O request size for a single command supported by the
88  * transport.  If the transport does not have a limit, returns 0.
89  */
90 uint64_t nvmf_max_xfer_size(struct nvmf_qpair *qp);
91 
92 /* Controller-specific APIs. */
93 
94 /*
95  * Largest I/O command capsule size (IOCCSZ) supported by the
96  * transport.  If the transport does not have a limit, returns 0.
97  */
98 uint32_t nvmf_max_ioccsz(struct nvmf_qpair *qp);
99 
100 /*
101  * A controller calls this function to check for any
102  * transport-specific errors (invalid fields) in a received command
103  * capsule.  The callback returns a generic command status value:
104  * NVME_SC_SUCCESS if no error is found.
105  */
106 uint8_t	nvmf_validate_command_capsule(struct nvmf_capsule *nc);
107 
108 /*
109  * A controller calls this function to query the amount of data
110  * associated with a command capsule.
111  */
112 size_t	nvmf_capsule_data_len(const struct nvmf_capsule *cc);
113 
114 /*
115  * A controller calls this function to receive data associated with a
116  * command capsule (e.g. the data for a WRITE command).  This can
117  * either return in-capsule data or fetch data from the host
118  * (e.g. using a R2T PDU over TCP).  The received command capsule
119  * should be passed in 'nc'.  The received data is stored in 'mem'.
120  * If this function returns success, then the callback will be invoked
121  * once the operation has completed.  Note that the callback might be
122  * invoked before this function returns.
123  */
124 int	nvmf_receive_controller_data(struct nvmf_capsule *nc,
125     uint32_t data_offset, struct memdesc *mem, size_t len,
126     nvmf_io_complete_t *complete_cb, void *cb_arg);
127 
128 /*
129  * A controller calls this function to send data in response to a
130  * command prior to sending a response capsule.  If an error occurs,
131  * the function returns a generic status completion code to be sent in
132  * the following CQE.  Note that the transfer might send a subset of
133  * the data requested by nc.  If the transfer succeeds, this function
134  * can return one of the following values:
135  *
136  * - NVME_SC_SUCCESS: The transfer has completed successfully and the
137  *   caller should send a success CQE in a response capsule.
138  *
139  * - NVMF_SUCCESS_SENT: The transfer has completed successfully and
140  *   the transport layer has sent an implicit success CQE to the
141  *   remote host (e.g. the SUCCESS flag for TCP).  The caller should
142  *   not send a response capsule.
143  *
144  * - NVMF_MORE: The transfer has completed successfully, but the
145  *   transfer did not complete the data buffer.
146  *
147  * The mbuf chain in 'm' is consumed by this function even if an error
148  * is returned.
149  */
150 u_int	nvmf_send_controller_data(struct nvmf_capsule *nc,
151     uint32_t data_offset, struct mbuf *m, size_t len);
152 
153 #define	NVMF_SUCCESS_SENT	0x100
154 #define	NVMF_MORE		0x101
155 
156 /* Helper APIs for nvlists used in icotls. */
157 
158 /*
159  * Pack the nvlist nvl and copyout to the buffer described by nv.
160  */
161 int	nvmf_pack_ioc_nvlist(const nvlist_t *nvl, struct nvmf_ioc_nv *nv);
162 
163 /*
164  * Copyin and unpack an nvlist described by nv.  The unpacked nvlist
165  * is returned in *nvlp on success.
166  */
167 int	nvmf_unpack_ioc_nvlist(const struct nvmf_ioc_nv *nv, nvlist_t **nvlp);
168 
169 /*
170  * Returns true if a qpair handoff nvlist has all the required
171  * transport-independent values.
172  */
173 bool	nvmf_validate_qpair_nvlist(const nvlist_t *nvl, bool controller);
174 
175 #endif /* !__NVMF_TRANSPORT_H__ */
176