12da066efSJohn Baldwin /*- 22da066efSJohn Baldwin * SPDX-License-Identifier: BSD-2-Clause 32da066efSJohn Baldwin * 42da066efSJohn Baldwin * Copyright (c) 2022-2024 Chelsio Communications, Inc. 52da066efSJohn Baldwin * Written by: John Baldwin <jhb@FreeBSD.org> 62da066efSJohn Baldwin */ 72da066efSJohn Baldwin 82da066efSJohn Baldwin #ifndef __LIBNVMF_H__ 92da066efSJohn Baldwin #define __LIBNVMF_H__ 102da066efSJohn Baldwin 11365b89e8SJohn Baldwin #include <sys/_nv.h> 122da066efSJohn Baldwin #include <sys/uio.h> 132da066efSJohn Baldwin #include <stdbool.h> 142da066efSJohn Baldwin #include <stddef.h> 152da066efSJohn Baldwin #include <dev/nvme/nvme.h> 162da066efSJohn Baldwin #include <dev/nvmf/nvmf.h> 172da066efSJohn Baldwin #include <dev/nvmf/nvmf_proto.h> 182da066efSJohn Baldwin 192da066efSJohn Baldwin struct nvmf_capsule; 202da066efSJohn Baldwin struct nvmf_association; 212da066efSJohn Baldwin struct nvmf_qpair; 222da066efSJohn Baldwin 232da066efSJohn Baldwin /* 242da066efSJohn Baldwin * Parameters shared by all queue-pairs of an association. Note that 252da066efSJohn Baldwin * this contains the requested values used to initiate transport 262da066efSJohn Baldwin * negotiation. 272da066efSJohn Baldwin */ 282da066efSJohn Baldwin struct nvmf_association_params { 292da066efSJohn Baldwin bool sq_flow_control; /* SQ flow control required. */ 302da066efSJohn Baldwin bool dynamic_controller_model; /* Controller only */ 312da066efSJohn Baldwin uint16_t max_admin_qsize; /* Controller only */ 322da066efSJohn Baldwin uint32_t max_io_qsize; /* Controller only, 0 for discovery */ 332da066efSJohn Baldwin union { 342da066efSJohn Baldwin struct { 352da066efSJohn Baldwin uint8_t pda; /* Tx-side PDA. */ 362da066efSJohn Baldwin bool header_digests; 372da066efSJohn Baldwin bool data_digests; 382da066efSJohn Baldwin uint32_t maxr2t; /* Host only */ 392da066efSJohn Baldwin uint32_t maxh2cdata; /* Controller only */ 402da066efSJohn Baldwin } tcp; 412da066efSJohn Baldwin }; 422da066efSJohn Baldwin }; 432da066efSJohn Baldwin 442da066efSJohn Baldwin /* Parameters specific to a single queue pair of an association. */ 452da066efSJohn Baldwin struct nvmf_qpair_params { 462da066efSJohn Baldwin bool admin; /* Host only */ 472da066efSJohn Baldwin union { 482da066efSJohn Baldwin struct { 492da066efSJohn Baldwin int fd; 502da066efSJohn Baldwin } tcp; 512da066efSJohn Baldwin }; 522da066efSJohn Baldwin }; 532da066efSJohn Baldwin 542da066efSJohn Baldwin /* Transport-independent APIs. */ 552da066efSJohn Baldwin 562da066efSJohn Baldwin /* 572da066efSJohn Baldwin * A host should allocate a new association for each association with 582da066efSJohn Baldwin * a controller. After the admin queue has been allocated and the 592da066efSJohn Baldwin * controller's data has been fetched, it should be passed to 602da066efSJohn Baldwin * nvmf_update_association to update internal transport-specific 612da066efSJohn Baldwin * parameters before allocating I/O queues. 622da066efSJohn Baldwin * 632da066efSJohn Baldwin * A controller uses a single association to manage all incoming 642da066efSJohn Baldwin * queues since it is not known until after parsing the CONNECT 652da066efSJohn Baldwin * command which transport queues are admin vs I/O and which 662da066efSJohn Baldwin * controller they are created against. 672da066efSJohn Baldwin */ 682da066efSJohn Baldwin struct nvmf_association *nvmf_allocate_association(enum nvmf_trtype trtype, 692da066efSJohn Baldwin bool controller, const struct nvmf_association_params *params); 702da066efSJohn Baldwin void nvmf_update_assocation(struct nvmf_association *na, 712da066efSJohn Baldwin const struct nvme_controller_data *cdata); 722da066efSJohn Baldwin void nvmf_free_association(struct nvmf_association *na); 732da066efSJohn Baldwin 742da066efSJohn Baldwin /* The most recent association-wide error message. */ 752da066efSJohn Baldwin const char *nvmf_association_error(const struct nvmf_association *na); 762da066efSJohn Baldwin 772da066efSJohn Baldwin /* 782da066efSJohn Baldwin * A queue pair represents either an Admin or I/O 792da066efSJohn Baldwin * submission/completion queue pair. 802da066efSJohn Baldwin * 812da066efSJohn Baldwin * Each open qpair holds a reference on its association. Once queue 822da066efSJohn Baldwin * pairs are allocated, callers can safely free the association to 832da066efSJohn Baldwin * ease bookkeeping. 842da066efSJohn Baldwin * 852da066efSJohn Baldwin * If nvmf_allocate_qpair fails, a detailed error message can be obtained 862da066efSJohn Baldwin * from nvmf_association_error. 872da066efSJohn Baldwin */ 882da066efSJohn Baldwin struct nvmf_qpair *nvmf_allocate_qpair(struct nvmf_association *na, 892da066efSJohn Baldwin const struct nvmf_qpair_params *params); 902da066efSJohn Baldwin void nvmf_free_qpair(struct nvmf_qpair *qp); 912da066efSJohn Baldwin 922da066efSJohn Baldwin /* 932da066efSJohn Baldwin * Capsules are either commands (host -> controller) or responses 942da066efSJohn Baldwin * (controller -> host). A single data buffer segment may be 952da066efSJohn Baldwin * associated with a command capsule. Transmitted data is not copied 962da066efSJohn Baldwin * by this API but instead must be preserved until the capsule is 972da066efSJohn Baldwin * transmitted and freed. 982da066efSJohn Baldwin */ 992da066efSJohn Baldwin struct nvmf_capsule *nvmf_allocate_command(struct nvmf_qpair *qp, 1002da066efSJohn Baldwin const void *sqe); 1012da066efSJohn Baldwin struct nvmf_capsule *nvmf_allocate_response(struct nvmf_qpair *qp, 1022da066efSJohn Baldwin const void *cqe); 1032da066efSJohn Baldwin void nvmf_free_capsule(struct nvmf_capsule *nc); 1042da066efSJohn Baldwin int nvmf_capsule_append_data(struct nvmf_capsule *nc, 1052da066efSJohn Baldwin void *buf, size_t len, bool send); 1062da066efSJohn Baldwin int nvmf_transmit_capsule(struct nvmf_capsule *nc); 1072da066efSJohn Baldwin int nvmf_receive_capsule(struct nvmf_qpair *qp, struct nvmf_capsule **ncp); 1082da066efSJohn Baldwin const void *nvmf_capsule_sqe(const struct nvmf_capsule *nc); 1092da066efSJohn Baldwin const void *nvmf_capsule_cqe(const struct nvmf_capsule *nc); 1102da066efSJohn Baldwin 1112da066efSJohn Baldwin /* Return a string name for a transport type. */ 1122da066efSJohn Baldwin const char *nvmf_transport_type(uint8_t trtype); 1132da066efSJohn Baldwin 1142da066efSJohn Baldwin /* Validate a NVMe Qualified Name. */ 1152da066efSJohn Baldwin bool nvmf_nqn_valid(const char *nqn); 1162da066efSJohn Baldwin 1172da066efSJohn Baldwin /* Controller-specific APIs. */ 1182da066efSJohn Baldwin 1192da066efSJohn Baldwin /* 1202da066efSJohn Baldwin * A controller calls this function to check for any 1212da066efSJohn Baldwin * transport-specific errors (invalid fields) in a received command 1222da066efSJohn Baldwin * capsule. The callback returns a generic command status value: 1232da066efSJohn Baldwin * NVME_SC_SUCCESS if no error is found. 1242da066efSJohn Baldwin */ 1252da066efSJohn Baldwin uint8_t nvmf_validate_command_capsule(const struct nvmf_capsule *nc); 1262da066efSJohn Baldwin 1272da066efSJohn Baldwin /* 1282da066efSJohn Baldwin * A controller calls this function to query the amount of data 1292da066efSJohn Baldwin * associated with a command capsule. 1302da066efSJohn Baldwin */ 1312da066efSJohn Baldwin size_t nvmf_capsule_data_len(const struct nvmf_capsule *cc); 1322da066efSJohn Baldwin 1332da066efSJohn Baldwin /* 1342da066efSJohn Baldwin * A controller calls this function to receive data associated with a 1352da066efSJohn Baldwin * command capsule (e.g. the data for a WRITE command). This can 1362da066efSJohn Baldwin * either return in-capsule data or fetch data from the host 1372da066efSJohn Baldwin * (e.g. using a R2T PDU over TCP). The received command capsule 1382da066efSJohn Baldwin * should be passed in 'nc'. The received data is stored in '*buf'. 1392da066efSJohn Baldwin */ 1402da066efSJohn Baldwin int nvmf_receive_controller_data(const struct nvmf_capsule *nc, 1412da066efSJohn Baldwin uint32_t data_offset, void *buf, size_t len); 1422da066efSJohn Baldwin 1432da066efSJohn Baldwin /* 1442da066efSJohn Baldwin * A controller calls this function to send data in response to a 1452da066efSJohn Baldwin * command along with a response capsule. If the data transfer 1462da066efSJohn Baldwin * succeeds, a success response is sent. If the data transfer fails, 1472da066efSJohn Baldwin * an appropriate error status capsule is sent. Regardless, a 1482da066efSJohn Baldwin * response capsule is always sent. 1492da066efSJohn Baldwin */ 1502da066efSJohn Baldwin int nvmf_send_controller_data(const struct nvmf_capsule *nc, 1512da066efSJohn Baldwin const void *buf, size_t len); 1522da066efSJohn Baldwin 1532da066efSJohn Baldwin /* 1542da066efSJohn Baldwin * Construct a CQE for a reply to a command capsule in 'nc' with the 1552da066efSJohn Baldwin * completion status 'status'. This is useful when additional CQE 1562da066efSJohn Baldwin * info is required beyond the completion status. 1572da066efSJohn Baldwin */ 1582da066efSJohn Baldwin void nvmf_init_cqe(void *cqe, const struct nvmf_capsule *nc, 1592da066efSJohn Baldwin uint16_t status); 1602da066efSJohn Baldwin 1612da066efSJohn Baldwin /* 1622da066efSJohn Baldwin * Construct and send a response capsule to a command capsule with 1632da066efSJohn Baldwin * the supplied CQE. 1642da066efSJohn Baldwin */ 1652da066efSJohn Baldwin int nvmf_send_response(const struct nvmf_capsule *nc, const void *cqe); 1662da066efSJohn Baldwin 1672da066efSJohn Baldwin /* 1682da066efSJohn Baldwin * Wait for a single command capsule and return it in *ncp. This can 1692da066efSJohn Baldwin * fail if an invalid capsule is received or an I/O error occurs. 1702da066efSJohn Baldwin */ 1712da066efSJohn Baldwin int nvmf_controller_receive_capsule(struct nvmf_qpair *qp, 1722da066efSJohn Baldwin struct nvmf_capsule **ncp); 1732da066efSJohn Baldwin 1742da066efSJohn Baldwin /* Send a response capsule from a controller. */ 1752da066efSJohn Baldwin int nvmf_controller_transmit_response(struct nvmf_capsule *nc); 1762da066efSJohn Baldwin 1772da066efSJohn Baldwin /* Construct and send an error response capsule. */ 1782da066efSJohn Baldwin int nvmf_send_error(const struct nvmf_capsule *cc, uint8_t sc_type, 1792da066efSJohn Baldwin uint8_t sc_status); 1802da066efSJohn Baldwin 1812da066efSJohn Baldwin /* 1822da066efSJohn Baldwin * Construct and send an error response capsule using a generic status 1832da066efSJohn Baldwin * code. 1842da066efSJohn Baldwin */ 1852da066efSJohn Baldwin int nvmf_send_generic_error(const struct nvmf_capsule *nc, 1862da066efSJohn Baldwin uint8_t sc_status); 1872da066efSJohn Baldwin 1882da066efSJohn Baldwin /* Construct and send a simple success response capsule. */ 1892da066efSJohn Baldwin int nvmf_send_success(const struct nvmf_capsule *nc); 1902da066efSJohn Baldwin 1912da066efSJohn Baldwin /* 1922da066efSJohn Baldwin * Allocate a new queue pair and wait for the CONNECT command capsule. 1932da066efSJohn Baldwin * If this fails, a detailed error message can be obtained from 1942da066efSJohn Baldwin * nvmf_association_error. On success, the command capsule is saved 1952da066efSJohn Baldwin * in '*ccp' and the connect data is saved in 'data'. The caller 1962da066efSJohn Baldwin * must send an explicit response and free the the command capsule. 1972da066efSJohn Baldwin */ 1982da066efSJohn Baldwin struct nvmf_qpair *nvmf_accept(struct nvmf_association *na, 1992da066efSJohn Baldwin const struct nvmf_qpair_params *params, struct nvmf_capsule **ccp, 2002da066efSJohn Baldwin struct nvmf_fabric_connect_data *data); 2012da066efSJohn Baldwin 2022da066efSJohn Baldwin /* 2032da066efSJohn Baldwin * Construct and send a response capsule with the Fabrics CONNECT 2042da066efSJohn Baldwin * invalid parameters error status. If data is true the offset is 2052da066efSJohn Baldwin * relative to the CONNECT data structure, otherwise the offset is 2062da066efSJohn Baldwin * relative to the SQE. 2072da066efSJohn Baldwin */ 2082da066efSJohn Baldwin void nvmf_connect_invalid_parameters(const struct nvmf_capsule *cc, 2092da066efSJohn Baldwin bool data, uint16_t offset); 2102da066efSJohn Baldwin 2112da066efSJohn Baldwin /* Construct and send a response capsule for a successful CONNECT. */ 2122da066efSJohn Baldwin int nvmf_finish_accept(const struct nvmf_capsule *cc, uint16_t cntlid); 2132da066efSJohn Baldwin 2142da066efSJohn Baldwin /* Compute the initial state of CAP for a controller. */ 2152da066efSJohn Baldwin uint64_t nvmf_controller_cap(struct nvmf_qpair *qp); 2162da066efSJohn Baldwin 2172da066efSJohn Baldwin /* Generate a serial number string from a host ID. */ 2182da066efSJohn Baldwin void nvmf_controller_serial(char *buf, size_t len, u_long hostid); 2192da066efSJohn Baldwin 2202da066efSJohn Baldwin /* 2212da066efSJohn Baldwin * Populate an Identify Controller data structure for a Discovery 2222da066efSJohn Baldwin * controller. 2232da066efSJohn Baldwin */ 2242da066efSJohn Baldwin void nvmf_init_discovery_controller_data(struct nvmf_qpair *qp, 2252da066efSJohn Baldwin struct nvme_controller_data *cdata); 2262da066efSJohn Baldwin 2272da066efSJohn Baldwin /* 2282da066efSJohn Baldwin * Populate an Identify Controller data structure for an I/O 2292da066efSJohn Baldwin * controller. 2302da066efSJohn Baldwin */ 2312da066efSJohn Baldwin void nvmf_init_io_controller_data(struct nvmf_qpair *qp, const char *serial, 2322da066efSJohn Baldwin const char *subnqn, int nn, uint32_t ioccsz, 2332da066efSJohn Baldwin struct nvme_controller_data *cdata); 2342da066efSJohn Baldwin 2352da066efSJohn Baldwin /* 2362da066efSJohn Baldwin * Validate if a new value for CC is legal given the existing values of 2372da066efSJohn Baldwin * CAP and CC. 2382da066efSJohn Baldwin */ 2392da066efSJohn Baldwin bool nvmf_validate_cc(struct nvmf_qpair *qp, uint64_t cap, uint32_t old_cc, 2402da066efSJohn Baldwin uint32_t new_cc); 2412da066efSJohn Baldwin 2422da066efSJohn Baldwin /* Return the log page id (LID) of a GET_LOG_PAGE command. */ 2432da066efSJohn Baldwin uint8_t nvmf_get_log_page_id(const struct nvme_command *cmd); 2442da066efSJohn Baldwin 2452da066efSJohn Baldwin /* Return the requested data length of a GET_LOG_PAGE command. */ 2462da066efSJohn Baldwin uint64_t nvmf_get_log_page_length(const struct nvme_command *cmd); 2472da066efSJohn Baldwin 2482da066efSJohn Baldwin /* Return the requested data offset of a GET_LOG_PAGE command. */ 2492da066efSJohn Baldwin uint64_t nvmf_get_log_page_offset(const struct nvme_command *cmd); 2502da066efSJohn Baldwin 2512da066efSJohn Baldwin /* Prepare to handoff a controller qpair. */ 2522da066efSJohn Baldwin int nvmf_handoff_controller_qpair(struct nvmf_qpair *qp, 253365b89e8SJohn Baldwin const struct nvmf_fabric_connect_cmd *cmd, 254365b89e8SJohn Baldwin const struct nvmf_fabric_connect_data *data, struct nvmf_ioc_nv *nv); 2552da066efSJohn Baldwin 2562da066efSJohn Baldwin /* Host-specific APIs. */ 2572da066efSJohn Baldwin 2582da066efSJohn Baldwin /* 2592da066efSJohn Baldwin * Connect to an admin or I/O queue. If this fails, a detailed error 2602da066efSJohn Baldwin * message can be obtained from nvmf_association_error. 2612da066efSJohn Baldwin */ 2622da066efSJohn Baldwin struct nvmf_qpair *nvmf_connect(struct nvmf_association *na, 2632da066efSJohn Baldwin const struct nvmf_qpair_params *params, uint16_t qid, u_int queue_size, 2642da066efSJohn Baldwin const uint8_t hostid[16], uint16_t cntlid, const char *subnqn, 2652da066efSJohn Baldwin const char *hostnqn, uint32_t kato); 2662da066efSJohn Baldwin 2672da066efSJohn Baldwin /* Return the CNTLID for a queue returned from CONNECT. */ 2682da066efSJohn Baldwin uint16_t nvmf_cntlid(struct nvmf_qpair *qp); 2692da066efSJohn Baldwin 2702da066efSJohn Baldwin /* 2712da066efSJohn Baldwin * Send a command to the controller. This can fail with EBUSY if the 2722da066efSJohn Baldwin * submission queue is full. 2732da066efSJohn Baldwin */ 2742da066efSJohn Baldwin int nvmf_host_transmit_command(struct nvmf_capsule *nc); 2752da066efSJohn Baldwin 2762da066efSJohn Baldwin /* 2772da066efSJohn Baldwin * Wait for a response to a command. If there are no outstanding 2782da066efSJohn Baldwin * commands in the SQ, fails with EWOULDBLOCK. 2792da066efSJohn Baldwin */ 2802da066efSJohn Baldwin int nvmf_host_receive_response(struct nvmf_qpair *qp, 2812da066efSJohn Baldwin struct nvmf_capsule **rcp); 2822da066efSJohn Baldwin 2832da066efSJohn Baldwin /* 2842da066efSJohn Baldwin * Wait for a response to a specific command. The command must have been 2852da066efSJohn Baldwin * succesfully sent previously. 2862da066efSJohn Baldwin */ 2872da066efSJohn Baldwin int nvmf_host_wait_for_response(struct nvmf_capsule *cc, 2882da066efSJohn Baldwin struct nvmf_capsule **rcp); 2892da066efSJohn Baldwin 2902da066efSJohn Baldwin /* Build a KeepAlive command. */ 2912da066efSJohn Baldwin struct nvmf_capsule *nvmf_keepalive(struct nvmf_qpair *qp); 2922da066efSJohn Baldwin 2932da066efSJohn Baldwin /* Read a controller property. */ 2942da066efSJohn Baldwin int nvmf_read_property(struct nvmf_qpair *qp, uint32_t offset, uint8_t size, 2952da066efSJohn Baldwin uint64_t *value); 2962da066efSJohn Baldwin 2972da066efSJohn Baldwin /* Write a controller property. */ 2982da066efSJohn Baldwin int nvmf_write_property(struct nvmf_qpair *qp, uint32_t offset, 2992da066efSJohn Baldwin uint8_t size, uint64_t value); 3002da066efSJohn Baldwin 3012da066efSJohn Baldwin /* Construct a 16-byte HostId from kern.hostuuid. */ 3022da066efSJohn Baldwin int nvmf_hostid_from_hostuuid(uint8_t hostid[16]); 3032da066efSJohn Baldwin 3042da066efSJohn Baldwin /* Construct a NQN from kern.hostuuid. */ 3052da066efSJohn Baldwin int nvmf_nqn_from_hostuuid(char nqn[NVMF_NQN_MAX_LEN]); 3062da066efSJohn Baldwin 3072da066efSJohn Baldwin /* Fetch controller data via IDENTIFY. */ 3082da066efSJohn Baldwin int nvmf_host_identify_controller(struct nvmf_qpair *qp, 3092da066efSJohn Baldwin struct nvme_controller_data *data); 3102da066efSJohn Baldwin 3112da066efSJohn Baldwin /* Fetch namespace data via IDENTIFY. */ 3122da066efSJohn Baldwin int nvmf_host_identify_namespace(struct nvmf_qpair *qp, uint32_t nsid, 3132da066efSJohn Baldwin struct nvme_namespace_data *nsdata); 3142da066efSJohn Baldwin 3152da066efSJohn Baldwin /* 3162da066efSJohn Baldwin * Fetch discovery log page. The memory for the log page is allocated 3172da066efSJohn Baldwin * by malloc() and returned in *logp. The caller must free the 3182da066efSJohn Baldwin * memory. 3192da066efSJohn Baldwin */ 3202da066efSJohn Baldwin int nvmf_host_fetch_discovery_log_page(struct nvmf_qpair *qp, 3212da066efSJohn Baldwin struct nvme_discovery_log **logp); 3222da066efSJohn Baldwin 3232da066efSJohn Baldwin /* 3248bba2c0fSJohn Baldwin * Construct a discovery log page entry that describes the connection 3258bba2c0fSJohn Baldwin * used by a host association's admin queue pair. 3268bba2c0fSJohn Baldwin */ 3278bba2c0fSJohn Baldwin int nvmf_init_dle_from_admin_qp(struct nvmf_qpair *qp, 3288bba2c0fSJohn Baldwin const struct nvme_controller_data *cdata, 3298bba2c0fSJohn Baldwin struct nvme_discovery_log_entry *dle); 3308bba2c0fSJohn Baldwin 3318bba2c0fSJohn Baldwin /* 3322da066efSJohn Baldwin * Request a desired number of I/O queues via SET_FEATURES. The 3332da066efSJohn Baldwin * number of actual I/O queues available is returned in *actual on 3342da066efSJohn Baldwin * success. 3352da066efSJohn Baldwin */ 3362da066efSJohn Baldwin int nvmf_host_request_queues(struct nvmf_qpair *qp, u_int requested, 3372da066efSJohn Baldwin u_int *actual); 3382da066efSJohn Baldwin 3392da066efSJohn Baldwin /* 3402da066efSJohn Baldwin * Handoff active host association to the kernel. This frees the 3412da066efSJohn Baldwin * qpairs (even on error). 3422da066efSJohn Baldwin */ 3438bba2c0fSJohn Baldwin int nvmf_handoff_host(const struct nvme_discovery_log_entry *dle, 3448bba2c0fSJohn Baldwin const char *hostnqn, struct nvmf_qpair *admin_qp, u_int num_queues, 3452da066efSJohn Baldwin struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata); 3462da066efSJohn Baldwin 3472da066efSJohn Baldwin /* 3482da066efSJohn Baldwin * Disconnect an active host association previously handed off to the 3492da066efSJohn Baldwin * kernel. *name is either the name of the device (nvmeX) for this 3502da066efSJohn Baldwin * association or the remote subsystem NQN. 3512da066efSJohn Baldwin */ 3522da066efSJohn Baldwin int nvmf_disconnect_host(const char *host); 3532da066efSJohn Baldwin 3542da066efSJohn Baldwin /* 3552da066efSJohn Baldwin * Disconnect all active host associations previously handed off to 3562da066efSJohn Baldwin * the kernel. 3572da066efSJohn Baldwin */ 3582da066efSJohn Baldwin int nvmf_disconnect_all(void); 3592da066efSJohn Baldwin 3602da066efSJohn Baldwin /* 3612da066efSJohn Baldwin * Fetch reconnect parameters from an existing kernel host to use for 362365b89e8SJohn Baldwin * establishing a new association. The caller must destroy the 363365b89e8SJohn Baldwin * returned nvlist. 3642da066efSJohn Baldwin */ 365365b89e8SJohn Baldwin int nvmf_reconnect_params(int fd, nvlist_t **nvlp); 3662da066efSJohn Baldwin 3672da066efSJohn Baldwin /* 3682da066efSJohn Baldwin * Handoff active host association to an existing host in the kernel. 3692da066efSJohn Baldwin * This frees the qpairs (even on error). 3702da066efSJohn Baldwin */ 3718bba2c0fSJohn Baldwin int nvmf_reconnect_host(int fd, const struct nvme_discovery_log_entry *dle, 3728bba2c0fSJohn Baldwin const char *hostnqn, struct nvmf_qpair *admin_qp, u_int num_queues, 3738bba2c0fSJohn Baldwin struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata); 3742da066efSJohn Baldwin 375*38e10839SJohn Baldwin /* 376*38e10839SJohn Baldwin * Fetch connection status from an existing kernel host. 377*38e10839SJohn Baldwin */ 378*38e10839SJohn Baldwin int nvmf_connection_status(int fd, nvlist_t **nvlp); 379*38e10839SJohn Baldwin 3802da066efSJohn Baldwin #endif /* !__LIBNVMF_H__ */ 381