1aa1207eaSJohn Baldwin /*- 2aa1207eaSJohn Baldwin * SPDX-License-Identifier: BSD-2-Clause 3aa1207eaSJohn Baldwin * 4aa1207eaSJohn Baldwin * Copyright (c) 2022-2024 Chelsio Communications, Inc. 5aa1207eaSJohn Baldwin * Written by: John Baldwin <jhb@FreeBSD.org> 6aa1207eaSJohn Baldwin */ 7aa1207eaSJohn Baldwin 8aa1207eaSJohn Baldwin #ifndef __NVMF_TRANSPORT_H__ 9aa1207eaSJohn Baldwin #define __NVMF_TRANSPORT_H__ 10aa1207eaSJohn Baldwin 11aa1207eaSJohn Baldwin /* 12aa1207eaSJohn Baldwin * Interface used by the Fabrics host (initiator) and controller 13aa1207eaSJohn Baldwin * (target) to send and receive capsules and associated data. 14aa1207eaSJohn Baldwin */ 15aa1207eaSJohn Baldwin 16365b89e8SJohn Baldwin #include <sys/_nv.h> 17aa1207eaSJohn Baldwin #include <sys/sysctl.h> 18aa1207eaSJohn Baldwin #include <dev/nvmf/nvmf_proto.h> 19aa1207eaSJohn Baldwin 20aa1207eaSJohn Baldwin struct mbuf; 21aa1207eaSJohn Baldwin struct memdesc; 22aa1207eaSJohn Baldwin struct nvmf_capsule; 23aa1207eaSJohn Baldwin struct nvmf_connection; 24365b89e8SJohn Baldwin struct nvmf_ioc_nv; 25aa1207eaSJohn Baldwin struct nvmf_qpair; 26aa1207eaSJohn Baldwin 27aa1207eaSJohn Baldwin SYSCTL_DECL(_kern_nvmf); 28aa1207eaSJohn Baldwin 29aa1207eaSJohn Baldwin /* 30aa1207eaSJohn Baldwin * Callback to invoke when an error occurs on a qpair. The last 31aa1207eaSJohn Baldwin * parameter is an error value. If the error value is zero, the qpair 32aa1207eaSJohn Baldwin * has been closed at the transport level rather than a transport 33aa1207eaSJohn Baldwin * error occuring. 34aa1207eaSJohn Baldwin */ 35aa1207eaSJohn Baldwin typedef void nvmf_qpair_error_t(void *, int); 36aa1207eaSJohn Baldwin 37aa1207eaSJohn Baldwin /* Callback to invoke when a capsule is received. */ 38aa1207eaSJohn Baldwin typedef void nvmf_capsule_receive_t(void *, struct nvmf_capsule *); 39aa1207eaSJohn Baldwin 40aa1207eaSJohn Baldwin /* 41aa1207eaSJohn Baldwin * Callback to invoke when an I/O request has completed. The second 42aa1207eaSJohn Baldwin * parameter is the amount of data transferred. The last parameter is 43aa1207eaSJohn Baldwin * an error value which is non-zero if the request did not complete 44aa1207eaSJohn Baldwin * successfully. A request with an error may complete partially. 45aa1207eaSJohn Baldwin */ 46aa1207eaSJohn Baldwin typedef void nvmf_io_complete_t(void *, size_t, int); 47aa1207eaSJohn Baldwin 48aa1207eaSJohn Baldwin /* 49aa1207eaSJohn Baldwin * A queue pair represents either an Admin or I/O 50aa1207eaSJohn Baldwin * submission/completion queue pair. The params contains negotiated 51aa1207eaSJohn Baldwin * values passed in from userland. 52aa1207eaSJohn Baldwin * 53aa1207eaSJohn Baldwin * Unlike libnvmf in userland, the kernel transport interface does not 54aa1207eaSJohn Baldwin * have any notion of an association. Instead, qpairs are 55aa1207eaSJohn Baldwin * independent. 56aa1207eaSJohn Baldwin */ 57aa1207eaSJohn Baldwin struct nvmf_qpair *nvmf_allocate_qpair(enum nvmf_trtype trtype, 58365b89e8SJohn Baldwin bool controller, const nvlist_t *params, 59aa1207eaSJohn Baldwin nvmf_qpair_error_t *error_cb, void *error_cb_arg, 60aa1207eaSJohn Baldwin nvmf_capsule_receive_t *receive_cb, void *receive_cb_arg); 61aa1207eaSJohn Baldwin void nvmf_free_qpair(struct nvmf_qpair *qp); 62aa1207eaSJohn Baldwin 63aa1207eaSJohn Baldwin /* 64aa1207eaSJohn Baldwin * Capsules are either commands (host -> controller) or responses 65aa1207eaSJohn Baldwin * (controller -> host). A data buffer may be associated with a 66aa1207eaSJohn Baldwin * command capsule. Transmitted data is not copied by this API but 67aa1207eaSJohn Baldwin * instead must be preserved until the completion callback is invoked 68aa1207eaSJohn Baldwin * to indicate capsule transmission has completed. 69aa1207eaSJohn Baldwin */ 70aa1207eaSJohn Baldwin struct nvmf_capsule *nvmf_allocate_command(struct nvmf_qpair *qp, 71aa1207eaSJohn Baldwin const void *sqe, int how); 72aa1207eaSJohn Baldwin struct nvmf_capsule *nvmf_allocate_response(struct nvmf_qpair *qp, 73aa1207eaSJohn Baldwin const void *cqe, int how); 74aa1207eaSJohn Baldwin void nvmf_free_capsule(struct nvmf_capsule *nc); 75aa1207eaSJohn Baldwin int nvmf_capsule_append_data(struct nvmf_capsule *nc, 76aa1207eaSJohn Baldwin struct memdesc *mem, size_t len, bool send, 77aa1207eaSJohn Baldwin nvmf_io_complete_t *complete_cb, void *cb_arg); 78aa1207eaSJohn Baldwin int nvmf_transmit_capsule(struct nvmf_capsule *nc); 79aa1207eaSJohn Baldwin void nvmf_abort_capsule_data(struct nvmf_capsule *nc, int error); 80aa1207eaSJohn Baldwin void *nvmf_capsule_sqe(struct nvmf_capsule *nc); 81aa1207eaSJohn Baldwin void *nvmf_capsule_cqe(struct nvmf_capsule *nc); 824d3b659fSJohn Baldwin bool nvmf_sqhd_valid(struct nvmf_capsule *nc); 83aa1207eaSJohn Baldwin 8401dd6a83SJohn Baldwin /* Host-specific APIs. */ 8501dd6a83SJohn Baldwin 8601dd6a83SJohn Baldwin /* 8701dd6a83SJohn Baldwin * Largest I/O request size for a single command supported by the 8801dd6a83SJohn Baldwin * transport. If the transport does not have a limit, returns 0. 8901dd6a83SJohn Baldwin */ 9001dd6a83SJohn Baldwin uint64_t nvmf_max_xfer_size(struct nvmf_qpair *qp); 9101dd6a83SJohn Baldwin 92aa1207eaSJohn Baldwin /* Controller-specific APIs. */ 93aa1207eaSJohn Baldwin 94aa1207eaSJohn Baldwin /* 95c1b3c5f5SJohn Baldwin * Largest I/O command capsule size (IOCCSZ) supported by the 96c1b3c5f5SJohn Baldwin * transport. If the transport does not have a limit, returns 0. 97c1b3c5f5SJohn Baldwin */ 98c1b3c5f5SJohn Baldwin uint32_t nvmf_max_ioccsz(struct nvmf_qpair *qp); 99c1b3c5f5SJohn Baldwin 100c1b3c5f5SJohn Baldwin /* 101aa1207eaSJohn Baldwin * A controller calls this function to check for any 102aa1207eaSJohn Baldwin * transport-specific errors (invalid fields) in a received command 103aa1207eaSJohn Baldwin * capsule. The callback returns a generic command status value: 104aa1207eaSJohn Baldwin * NVME_SC_SUCCESS if no error is found. 105aa1207eaSJohn Baldwin */ 106aa1207eaSJohn Baldwin uint8_t nvmf_validate_command_capsule(struct nvmf_capsule *nc); 107aa1207eaSJohn Baldwin 108aa1207eaSJohn Baldwin /* 109aa1207eaSJohn Baldwin * A controller calls this function to query the amount of data 110aa1207eaSJohn Baldwin * associated with a command capsule. 111aa1207eaSJohn Baldwin */ 112aa1207eaSJohn Baldwin size_t nvmf_capsule_data_len(const struct nvmf_capsule *cc); 113aa1207eaSJohn Baldwin 114aa1207eaSJohn Baldwin /* 115aa1207eaSJohn Baldwin * A controller calls this function to receive data associated with a 116aa1207eaSJohn Baldwin * command capsule (e.g. the data for a WRITE command). This can 117aa1207eaSJohn Baldwin * either return in-capsule data or fetch data from the host 118aa1207eaSJohn Baldwin * (e.g. using a R2T PDU over TCP). The received command capsule 119aa1207eaSJohn Baldwin * should be passed in 'nc'. The received data is stored in 'mem'. 120aa1207eaSJohn Baldwin * If this function returns success, then the callback will be invoked 121aa1207eaSJohn Baldwin * once the operation has completed. Note that the callback might be 122aa1207eaSJohn Baldwin * invoked before this function returns. 123aa1207eaSJohn Baldwin */ 124aa1207eaSJohn Baldwin int nvmf_receive_controller_data(struct nvmf_capsule *nc, 125aa1207eaSJohn Baldwin uint32_t data_offset, struct memdesc *mem, size_t len, 126aa1207eaSJohn Baldwin nvmf_io_complete_t *complete_cb, void *cb_arg); 127aa1207eaSJohn Baldwin 128aa1207eaSJohn Baldwin /* 129aa1207eaSJohn Baldwin * A controller calls this function to send data in response to a 130aa1207eaSJohn Baldwin * command prior to sending a response capsule. If an error occurs, 131aa1207eaSJohn Baldwin * the function returns a generic status completion code to be sent in 132aa1207eaSJohn Baldwin * the following CQE. Note that the transfer might send a subset of 133aa1207eaSJohn Baldwin * the data requested by nc. If the transfer succeeds, this function 134aa1207eaSJohn Baldwin * can return one of the following values: 135aa1207eaSJohn Baldwin * 136aa1207eaSJohn Baldwin * - NVME_SC_SUCCESS: The transfer has completed successfully and the 137aa1207eaSJohn Baldwin * caller should send a success CQE in a response capsule. 138aa1207eaSJohn Baldwin * 139aa1207eaSJohn Baldwin * - NVMF_SUCCESS_SENT: The transfer has completed successfully and 140aa1207eaSJohn Baldwin * the transport layer has sent an implicit success CQE to the 141aa1207eaSJohn Baldwin * remote host (e.g. the SUCCESS flag for TCP). The caller should 142aa1207eaSJohn Baldwin * not send a response capsule. 143aa1207eaSJohn Baldwin * 144aa1207eaSJohn Baldwin * - NVMF_MORE: The transfer has completed successfully, but the 145aa1207eaSJohn Baldwin * transfer did not complete the data buffer. 146aa1207eaSJohn Baldwin * 147aa1207eaSJohn Baldwin * The mbuf chain in 'm' is consumed by this function even if an error 148aa1207eaSJohn Baldwin * is returned. 149aa1207eaSJohn Baldwin */ 150aa1207eaSJohn Baldwin u_int nvmf_send_controller_data(struct nvmf_capsule *nc, 151aa1207eaSJohn Baldwin uint32_t data_offset, struct mbuf *m, size_t len); 152aa1207eaSJohn Baldwin 153aa1207eaSJohn Baldwin #define NVMF_SUCCESS_SENT 0x100 154aa1207eaSJohn Baldwin #define NVMF_MORE 0x101 155aa1207eaSJohn Baldwin 156365b89e8SJohn Baldwin /* Helper APIs for nvlists used in icotls. */ 157365b89e8SJohn Baldwin 158365b89e8SJohn Baldwin /* 159365b89e8SJohn Baldwin * Pack the nvlist nvl and copyout to the buffer described by nv. 160365b89e8SJohn Baldwin */ 161365b89e8SJohn Baldwin int nvmf_pack_ioc_nvlist(const nvlist_t *nvl, struct nvmf_ioc_nv *nv); 162365b89e8SJohn Baldwin 163365b89e8SJohn Baldwin /* 164365b89e8SJohn Baldwin * Copyin and unpack an nvlist described by nv. The unpacked nvlist 165365b89e8SJohn Baldwin * is returned in *nvlp on success. 166365b89e8SJohn Baldwin */ 167365b89e8SJohn Baldwin int nvmf_unpack_ioc_nvlist(const struct nvmf_ioc_nv *nv, nvlist_t **nvlp); 168365b89e8SJohn Baldwin 169365b89e8SJohn Baldwin /* 170365b89e8SJohn Baldwin * Returns true if a qpair handoff nvlist has all the required 171365b89e8SJohn Baldwin * transport-independent values. 172365b89e8SJohn Baldwin */ 173365b89e8SJohn Baldwin bool nvmf_validate_qpair_nvlist(const nvlist_t *nvl, bool controller); 174365b89e8SJohn Baldwin 175aa1207eaSJohn Baldwin #endif /* !__NVMF_TRANSPORT_H__ */ 176