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