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