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