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 18struct module; 19struct nvmf_io_request; 20 21struct 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. */ 46struct 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 62struct 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 */ 78struct 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 98static void __inline 99nvmf_qpair_error(struct nvmf_qpair *nq, int error) 100{ 101 nq->nq_error(nq->nq_error_arg, error); 102} 103 104static void __inline 105nvmf_capsule_received(struct nvmf_qpair *nq, struct nvmf_capsule *nc) 106{ 107 nq->nq_receive(nq->nq_receive_arg, nc); 108} 109 110static void __inline 111nvmf_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 116int nvmf_transport_module_handler(struct module *, int, void *); 117 118#define NVMF_TRANSPORT(name, ops) \ 119static moduledata_t nvmf_transport_##name##_mod = { \ 120 "nvmf/" #name, \ 121 nvmf_transport_module_handler, \ 122 &(ops) \ 123}; \ 124DECLARE_MODULE(nvmf_transport_##name, nvmf_transport_##name##_mod, \ 125 SI_SUB_DRIVERS, SI_ORDER_ANY); \ 126MODULE_DEPEND(nvmf_transport_##name, nvmf_transport, 1, 1, 1) 127 128#endif /* !__NVMF_TRANSPORT_INTERNAL_H__ */ 129