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