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 /* Limit on I/O command capsule size. */
29 uint32_t (*max_ioccsz)(struct nvmf_qpair *qp);
30
31 /* Limit on transfer size. */
32 uint64_t (*max_xfer_size)(struct nvmf_qpair *qp);
33
34 /* Capsule operations. */
35 struct nvmf_capsule *(*allocate_capsule)(struct nvmf_qpair *qp,
36 int how);
37 void (*free_capsule)(struct nvmf_capsule *nc);
38 int (*transmit_capsule)(struct nvmf_capsule *nc);
39 uint8_t (*validate_command_capsule)(struct nvmf_capsule *nc);
40
41 /* Transferring controller data. */
42 size_t (*capsule_data_len)(const struct nvmf_capsule *nc);
43 int (*receive_controller_data)(struct nvmf_capsule *nc,
44 uint32_t data_offset, struct nvmf_io_request *io);
45 u_int (*send_controller_data)(struct nvmf_capsule *nc,
46 uint32_t data_offset, struct mbuf *m, size_t len);
47
48 enum nvmf_trtype trtype;
49 int priority;
50 };
51
52 /* Either an Admin or I/O Submission/Completion Queue pair. */
53 struct nvmf_qpair {
54 struct nvmf_transport *nq_transport;
55 struct nvmf_transport_ops *nq_ops;
56 bool nq_controller;
57
58 /* Callback to invoke for a received capsule. */
59 nvmf_capsule_receive_t *nq_receive;
60 void *nq_receive_arg;
61
62 /* Callback to invoke for an error. */
63 nvmf_qpair_error_t *nq_error;
64 void *nq_error_arg;
65
66 bool nq_admin;
67 };
68
69 struct nvmf_io_request {
70 /*
71 * Data buffer contains io_len bytes in the backing store
72 * described by mem.
73 */
74 struct memdesc io_mem;
75 size_t io_len;
76 nvmf_io_complete_t *io_complete;
77 void *io_complete_arg;
78 };
79
80 /*
81 * Fabrics Command and Response Capsules. The Fabrics host
82 * (initiator) and controller (target) drivers work with capsules that
83 * are transmitted and received by a specific transport.
84 */
85 struct nvmf_capsule {
86 struct nvmf_qpair *nc_qpair;
87
88 /* Either a SQE or CQE. */
89 union {
90 struct nvme_command nc_sqe;
91 struct nvme_completion nc_cqe;
92 };
93 int nc_qe_len;
94
95 /*
96 * Is SQHD in received capsule valid? False for locally-
97 * synthesized responses.
98 */
99 bool nc_sqhd_valid;
100
101 bool nc_send_data;
102 struct nvmf_io_request nc_data;
103 };
104
105 static void __inline
nvmf_qpair_error(struct nvmf_qpair * nq,int error)106 nvmf_qpair_error(struct nvmf_qpair *nq, int error)
107 {
108 nq->nq_error(nq->nq_error_arg, error);
109 }
110
111 static void __inline
nvmf_capsule_received(struct nvmf_qpair * nq,struct nvmf_capsule * nc)112 nvmf_capsule_received(struct nvmf_qpair *nq, struct nvmf_capsule *nc)
113 {
114 nq->nq_receive(nq->nq_receive_arg, nc);
115 }
116
117 static void __inline
nvmf_complete_io_request(struct nvmf_io_request * io,size_t xfered,int error)118 nvmf_complete_io_request(struct nvmf_io_request *io, size_t xfered, int error)
119 {
120 io->io_complete(io->io_complete_arg, xfered, error);
121 }
122
123 int nvmf_transport_module_handler(struct module *, int, void *);
124
125 #define NVMF_TRANSPORT(name, ops) \
126 static moduledata_t nvmf_transport_##name##_mod = { \
127 "nvmf/" #name, \
128 nvmf_transport_module_handler, \
129 &(ops) \
130 }; \
131 DECLARE_MODULE(nvmf_transport_##name, nvmf_transport_##name##_mod, \
132 SI_SUB_DRIVERS, SI_ORDER_ANY); \
133 MODULE_DEPEND(nvmf_transport_##name, nvmf_transport, 1, 1, 1)
134
135 #endif /* !__NVMF_TRANSPORT_INTERNAL_H__ */
136