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 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 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 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