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