1*a15f7c96SJohn Baldwin /*- 2*a15f7c96SJohn Baldwin * SPDX-License-Identifier: BSD-2-Clause 3*a15f7c96SJohn Baldwin * 4*a15f7c96SJohn Baldwin * Copyright (c) 2023-2024 Chelsio Communications, Inc. 5*a15f7c96SJohn Baldwin * Written by: John Baldwin <jhb@FreeBSD.org> 6*a15f7c96SJohn Baldwin */ 7*a15f7c96SJohn Baldwin 8*a15f7c96SJohn Baldwin #ifndef __NVMFT_VAR_H__ 9*a15f7c96SJohn Baldwin #define __NVMFT_VAR_H__ 10*a15f7c96SJohn Baldwin 11*a15f7c96SJohn Baldwin #include <sys/_callout.h> 12*a15f7c96SJohn Baldwin #include <sys/refcount.h> 13*a15f7c96SJohn Baldwin #include <sys/taskqueue.h> 14*a15f7c96SJohn Baldwin 15*a15f7c96SJohn Baldwin #include <dev/nvmf/nvmf_proto.h> 16*a15f7c96SJohn Baldwin 17*a15f7c96SJohn Baldwin #include <cam/ctl/ctl.h> 18*a15f7c96SJohn Baldwin #include <cam/ctl/ctl_io.h> 19*a15f7c96SJohn Baldwin #include <cam/ctl/ctl_frontend.h> 20*a15f7c96SJohn Baldwin 21*a15f7c96SJohn Baldwin struct nvmf_capsule; 22*a15f7c96SJohn Baldwin struct nvmft_controller; 23*a15f7c96SJohn Baldwin struct nvmft_qpair; 24*a15f7c96SJohn Baldwin 25*a15f7c96SJohn Baldwin #define NVMFT_NUM_AER 16 26*a15f7c96SJohn Baldwin 27*a15f7c96SJohn Baldwin struct nvmft_port { 28*a15f7c96SJohn Baldwin TAILQ_ENTRY(nvmft_port) link; 29*a15f7c96SJohn Baldwin u_int refs; 30*a15f7c96SJohn Baldwin struct ctl_port port; 31*a15f7c96SJohn Baldwin struct nvme_controller_data cdata; 32*a15f7c96SJohn Baldwin struct nvme_firmware_page fp; 33*a15f7c96SJohn Baldwin uint64_t cap; 34*a15f7c96SJohn Baldwin uint32_t max_io_qsize; 35*a15f7c96SJohn Baldwin bool online; 36*a15f7c96SJohn Baldwin 37*a15f7c96SJohn Baldwin struct sx lock; 38*a15f7c96SJohn Baldwin 39*a15f7c96SJohn Baldwin struct unrhdr *ids; 40*a15f7c96SJohn Baldwin TAILQ_HEAD(, nvmft_controller) controllers; 41*a15f7c96SJohn Baldwin 42*a15f7c96SJohn Baldwin uint32_t *active_ns; 43*a15f7c96SJohn Baldwin u_int num_ns; 44*a15f7c96SJohn Baldwin }; 45*a15f7c96SJohn Baldwin 46*a15f7c96SJohn Baldwin struct nvmft_io_qpair { 47*a15f7c96SJohn Baldwin struct nvmft_qpair *qp; 48*a15f7c96SJohn Baldwin 49*a15f7c96SJohn Baldwin bool shutdown; 50*a15f7c96SJohn Baldwin }; 51*a15f7c96SJohn Baldwin 52*a15f7c96SJohn Baldwin struct nvmft_controller { 53*a15f7c96SJohn Baldwin struct nvmft_qpair *admin; 54*a15f7c96SJohn Baldwin struct nvmft_io_qpair *io_qpairs; 55*a15f7c96SJohn Baldwin u_int num_io_queues; 56*a15f7c96SJohn Baldwin bool shutdown; 57*a15f7c96SJohn Baldwin bool admin_closed; 58*a15f7c96SJohn Baldwin uint16_t cntlid; 59*a15f7c96SJohn Baldwin uint32_t cc; 60*a15f7c96SJohn Baldwin uint32_t csts; 61*a15f7c96SJohn Baldwin 62*a15f7c96SJohn Baldwin struct nvmft_port *np; 63*a15f7c96SJohn Baldwin struct mtx lock; 64*a15f7c96SJohn Baldwin 65*a15f7c96SJohn Baldwin struct nvme_controller_data cdata; 66*a15f7c96SJohn Baldwin struct nvme_health_information_page hip; 67*a15f7c96SJohn Baldwin sbintime_t create_time; 68*a15f7c96SJohn Baldwin sbintime_t start_busy; 69*a15f7c96SJohn Baldwin sbintime_t busy_total; 70*a15f7c96SJohn Baldwin uint16_t partial_dur; 71*a15f7c96SJohn Baldwin uint16_t partial_duw; 72*a15f7c96SJohn Baldwin 73*a15f7c96SJohn Baldwin uint8_t hostid[16]; 74*a15f7c96SJohn Baldwin uint8_t hostnqn[NVME_NQN_FIELD_SIZE]; 75*a15f7c96SJohn Baldwin u_int trtype; 76*a15f7c96SJohn Baldwin 77*a15f7c96SJohn Baldwin TAILQ_ENTRY(nvmft_controller) link; 78*a15f7c96SJohn Baldwin 79*a15f7c96SJohn Baldwin /* 80*a15f7c96SJohn Baldwin * Each queue can have at most UINT16_MAX commands, so the total 81*a15f7c96SJohn Baldwin * across all queues will fit in a uint32_t. 82*a15f7c96SJohn Baldwin */ 83*a15f7c96SJohn Baldwin uint32_t pending_commands; 84*a15f7c96SJohn Baldwin 85*a15f7c96SJohn Baldwin volatile int ka_active_traffic; 86*a15f7c96SJohn Baldwin struct callout ka_timer; 87*a15f7c96SJohn Baldwin sbintime_t ka_sbt; 88*a15f7c96SJohn Baldwin 89*a15f7c96SJohn Baldwin /* AER fields. */ 90*a15f7c96SJohn Baldwin uint32_t aer_mask; 91*a15f7c96SJohn Baldwin uint16_t aer_cids[NVMFT_NUM_AER]; 92*a15f7c96SJohn Baldwin uint8_t aer_pending; 93*a15f7c96SJohn Baldwin uint8_t aer_cidx; 94*a15f7c96SJohn Baldwin uint8_t aer_pidx; 95*a15f7c96SJohn Baldwin 96*a15f7c96SJohn Baldwin /* Changed namespace IDs. */ 97*a15f7c96SJohn Baldwin struct nvme_ns_list *changed_ns; 98*a15f7c96SJohn Baldwin bool changed_ns_reported; 99*a15f7c96SJohn Baldwin 100*a15f7c96SJohn Baldwin struct task shutdown_task; 101*a15f7c96SJohn Baldwin struct timeout_task terminate_task; 102*a15f7c96SJohn Baldwin }; 103*a15f7c96SJohn Baldwin 104*a15f7c96SJohn Baldwin MALLOC_DECLARE(M_NVMFT); 105*a15f7c96SJohn Baldwin 106*a15f7c96SJohn Baldwin /* ctl_frontend_nvmf.c */ 107*a15f7c96SJohn Baldwin void nvmft_port_free(struct nvmft_port *np); 108*a15f7c96SJohn Baldwin void nvmft_populate_active_nslist(struct nvmft_port *np, uint32_t nsid, 109*a15f7c96SJohn Baldwin struct nvme_ns_list *nslist); 110*a15f7c96SJohn Baldwin void nvmft_dispatch_command(struct nvmft_qpair *qp, 111*a15f7c96SJohn Baldwin struct nvmf_capsule *nc, bool admin); 112*a15f7c96SJohn Baldwin void nvmft_terminate_commands(struct nvmft_controller *ctrlr); 113*a15f7c96SJohn Baldwin 114*a15f7c96SJohn Baldwin /* nvmft_controller.c */ 115*a15f7c96SJohn Baldwin void nvmft_controller_error(struct nvmft_controller *ctrlr, 116*a15f7c96SJohn Baldwin struct nvmft_qpair *qp, int error); 117*a15f7c96SJohn Baldwin void nvmft_controller_lun_changed(struct nvmft_controller *ctrlr, 118*a15f7c96SJohn Baldwin int lun_id); 119*a15f7c96SJohn Baldwin void nvmft_handle_admin_command(struct nvmft_controller *ctrlr, 120*a15f7c96SJohn Baldwin struct nvmf_capsule *nc); 121*a15f7c96SJohn Baldwin void nvmft_handle_io_command(struct nvmft_qpair *qp, uint16_t qid, 122*a15f7c96SJohn Baldwin struct nvmf_capsule *nc); 123*a15f7c96SJohn Baldwin int nvmft_handoff_admin_queue(struct nvmft_port *np, 124*a15f7c96SJohn Baldwin const struct nvmf_handoff_controller_qpair *handoff, 125*a15f7c96SJohn Baldwin const struct nvmf_fabric_connect_cmd *cmd, 126*a15f7c96SJohn Baldwin const struct nvmf_fabric_connect_data *data); 127*a15f7c96SJohn Baldwin int nvmft_handoff_io_queue(struct nvmft_port *np, 128*a15f7c96SJohn Baldwin const struct nvmf_handoff_controller_qpair *handoff, 129*a15f7c96SJohn Baldwin const struct nvmf_fabric_connect_cmd *cmd, 130*a15f7c96SJohn Baldwin const struct nvmf_fabric_connect_data *data); 131*a15f7c96SJohn Baldwin int nvmft_printf(struct nvmft_controller *ctrlr, const char *fmt, ...) 132*a15f7c96SJohn Baldwin __printflike(2, 3); 133*a15f7c96SJohn Baldwin 134*a15f7c96SJohn Baldwin /* nvmft_qpair.c */ 135*a15f7c96SJohn Baldwin struct nvmft_qpair *nvmft_qpair_init(enum nvmf_trtype trtype, 136*a15f7c96SJohn Baldwin const struct nvmf_handoff_qpair_params *handoff, uint16_t qid, 137*a15f7c96SJohn Baldwin const char *name); 138*a15f7c96SJohn Baldwin void nvmft_qpair_shutdown(struct nvmft_qpair *qp); 139*a15f7c96SJohn Baldwin void nvmft_qpair_destroy(struct nvmft_qpair *qp); 140*a15f7c96SJohn Baldwin struct nvmft_controller *nvmft_qpair_ctrlr(struct nvmft_qpair *qp); 141*a15f7c96SJohn Baldwin uint16_t nvmft_qpair_id(struct nvmft_qpair *qp); 142*a15f7c96SJohn Baldwin const char *nvmft_qpair_name(struct nvmft_qpair *qp); 143*a15f7c96SJohn Baldwin void nvmft_command_completed(struct nvmft_qpair *qp, 144*a15f7c96SJohn Baldwin struct nvmf_capsule *nc); 145*a15f7c96SJohn Baldwin int nvmft_send_response(struct nvmft_qpair *qp, const void *cqe); 146*a15f7c96SJohn Baldwin void nvmft_init_cqe(void *cqe, struct nvmf_capsule *nc, uint16_t status); 147*a15f7c96SJohn Baldwin int nvmft_send_error(struct nvmft_qpair *qp, struct nvmf_capsule *nc, 148*a15f7c96SJohn Baldwin uint8_t sc_type, uint8_t sc_status); 149*a15f7c96SJohn Baldwin int nvmft_send_generic_error(struct nvmft_qpair *qp, 150*a15f7c96SJohn Baldwin struct nvmf_capsule *nc, uint8_t sc_status); 151*a15f7c96SJohn Baldwin int nvmft_send_success(struct nvmft_qpair *qp, 152*a15f7c96SJohn Baldwin struct nvmf_capsule *nc); 153*a15f7c96SJohn Baldwin void nvmft_connect_error(struct nvmft_qpair *qp, 154*a15f7c96SJohn Baldwin const struct nvmf_fabric_connect_cmd *cmd, uint8_t sc_type, 155*a15f7c96SJohn Baldwin uint8_t sc_status); 156*a15f7c96SJohn Baldwin void nvmft_connect_invalid_parameters(struct nvmft_qpair *qp, 157*a15f7c96SJohn Baldwin const struct nvmf_fabric_connect_cmd *cmd, bool data, uint16_t offset); 158*a15f7c96SJohn Baldwin int nvmft_finish_accept(struct nvmft_qpair *qp, 159*a15f7c96SJohn Baldwin const struct nvmf_fabric_connect_cmd *cmd, struct nvmft_controller *ctrlr); 160*a15f7c96SJohn Baldwin 161*a15f7c96SJohn Baldwin static __inline void 162*a15f7c96SJohn Baldwin nvmft_port_ref(struct nvmft_port *np) 163*a15f7c96SJohn Baldwin { 164*a15f7c96SJohn Baldwin refcount_acquire(&np->refs); 165*a15f7c96SJohn Baldwin } 166*a15f7c96SJohn Baldwin 167*a15f7c96SJohn Baldwin static __inline void 168*a15f7c96SJohn Baldwin nvmft_port_rele(struct nvmft_port *np) 169*a15f7c96SJohn Baldwin { 170*a15f7c96SJohn Baldwin if (refcount_release(&np->refs)) 171*a15f7c96SJohn Baldwin nvmft_port_free(np); 172*a15f7c96SJohn Baldwin } 173*a15f7c96SJohn Baldwin 174*a15f7c96SJohn Baldwin #endif /* !__NVMFT_VAR_H__ */ 175