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