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