xref: /freebsd/sys/dev/nvmf/nvmf_transport_internal.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_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