* BSD LICENSE
*
* Copyright (c) Intel Corporation. All rights reserved.
* Copyright (c) 2017, Western Digital Corporation or its affiliates.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
* @file
* NVMe driver public API
*
* @mainpage
*
* libnvme is a user space utility to provide control over NVMe,
* the host controller interface for drives based on PCI Express.
*
* \addtogroup libnvme
* @{
*/
#ifndef __LIBNVME_H__
#define __LIBNVME_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <libnvme/nvme_spec.h>
#ifndef __HAIKU__
#include <pciaccess.h>
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
* Log levels.
*/
enum nvme_log_level {
* Disable all log messages.
*/
NVME_LOG_NONE = 0,
* System is unusable.
*/
NVME_LOG_EMERG,
* Action must be taken immediately.
*/
NVME_LOG_ALERT,
* Critical conditions.
*/
NVME_LOG_CRIT,
* Error conditions.
*/
NVME_LOG_ERR,
* Warning conditions.
*/
NVME_LOG_WARNING,
* Normal but significant condition.
*/
NVME_LOG_NOTICE,
* Informational messages.
*/
NVME_LOG_INFO,
* Debug-level messages.
*/
NVME_LOG_DEBUG,
};
* Log facilities.
*/
enum nvme_log_facility {
* Standard output log facility
*/
NVME_LOG_STDOUT = 0x00000001,
* Regular file output log facility
*/
NVME_LOG_FILE = 0x00000002,
* syslog service output log facility
*/
NVME_LOG_SYSLOG = 0x00000004,
};
* @brief Initialize libnvme
*
* @param level Library log level
* @param facility Facility code
* @param path File name for the NVME_LOG_FILE facility
*
* This function must always be called first before any other
* function provided by libnvme. The arguments allow setting the
* initial log level and log facility so that any problem during
* initialization can be caught.
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_lib_init(enum nvme_log_level level,
enum nvme_log_facility facility, const char *path);
* @brief Set the library log level
*
* @param level Library log level
*/
extern void nvme_set_log_level(enum nvme_log_level level);
* @brief Get the current log level
*
* @return The current library log level.
*/
extern enum nvme_log_level nvme_get_log_level(void);
* @brief Change the library log facility
*
* @param facility Facility code
* @param path File name for the NVME_LOG_FILE facility
*
* Set th library log facility. On failure, the facility is
* always automatically set to stdout.
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_set_log_facility(enum nvme_log_facility facility,
const char *path);
* @brief Get the current library log facility.
*
* @return The current library log facility.
*/
extern enum nvme_log_facility nvme_get_log_facility(void);
* @brief Opaque handle to a controller returned by nvme_ctrlr_open().
*/
struct nvme_ctrlr;
* @brief Opaque handle to a namespace
*/
struct nvme_ns;
* @brief Opaque handle to an I/O queue pair
*/
struct nvme_qpair;
* @brief Capabilities register of a controller
*/
struct nvme_register_data {
* Maximum Queue Entries Supported indicates the maximum individual
* queue size that the controller supports. This is a 0’s based value,
* so 1 has to be added.
*/
unsigned int mqes;
};
* Length of the string for the serial number
*/
#define NVME_SERIAL_NUMBER_LENGTH NVME_SERIAL_NUMBER_CHARACTERS + 1
* Length of the string for the model number
*/
#define NVME_MODEL_NUMBER_LENGTH NVME_MODEL_NUMBER_CHARACTERS + 1
* @brief Controller information
*/
struct nvme_ctrlr_stat {
* PCI device vendor ID.
*/
unsigned short vendor_id;
* PCI device ID.
*/
unsigned short device_id;
* PCI device sub-vendor ID.
*/
unsigned short subvendor_id;
* PCI sub-device ID.
*/
unsigned short subdevice_id;
* PCI device class.
*/
unsigned int device_class;
* PCI device revision.
*/
unsigned char revision;
* PCI slot domain.
*/
unsigned int domain;
* PCI slot bus.
*/
unsigned int bus;
* PCI slot bus device number.
*/
unsigned int dev;
* PCI slot device function.
*/
unsigned int func;
* Serial number
*/
char sn[NVME_SERIAL_NUMBER_LENGTH];
* Model number
*/
char mn[NVME_MODEL_NUMBER_LENGTH];
* Maximum transfer size.
*/
size_t max_xfer_size;
* All the log pages supported.
*/
bool log_pages[256];
* Whether SGL is supported by the controller.
*
* Note that this does not mean all SGL requests will fail;
* many are convertible into standard (PRP) requests by libnvme.
*/
bool sgl_supported;
* All the features supported.
*/
bool features[256];
* Number of valid namespaces in the array of namespace IDs.
*/
unsigned int nr_ns;
* Array of valid namespace IDs of the controller.
* Namspeace IDs are integers between 1 and NVME_MAX_NS
*/
unsigned int ns_ids[NVME_MAX_NS];
* Maximum number of I/O queue pairs
*/
unsigned int max_io_qpairs;
* Number of I/O queue pairs allocated
*/
unsigned int io_qpairs;
* Number of I/O queue pairs enabled
*/
unsigned int enabled_io_qpairs;
* IO qpairs maximum entries
*/
unsigned int max_qd;
};
* @brief NVMe controller options
*
* Allow the user to request non-default options.
*/
struct nvme_ctrlr_opts {
* Number of I/O queues to initialize.
* (default: all possible I/O queues)
*/
unsigned int io_queues;
* Enable submission queue in controller memory buffer
* (default: false)
*/
bool use_cmb_sqs;
* Type of arbitration mechanism.
* (default: round-robin == NVME_CC_AMS_RR)
*/
enum nvme_cc_ams arb_mechanism;
};
* @brief Namespace command support flags
*/
enum nvme_ns_flags {
* The deallocate command is supported.
*/
NVME_NS_DEALLOCATE_SUPPORTED = 0x1,
* The flush command is supported.
*/
NVME_NS_FLUSH_SUPPORTED = 0x2,
* The reservation command is supported.
*/
NVME_NS_RESERVATION_SUPPORTED = 0x4,
* The write zeroes command is supported.
*/
NVME_NS_WRITE_ZEROES_SUPPORTED = 0x8,
* The end-to-end data protection is supported.
*/
NVME_NS_DPS_PI_SUPPORTED = 0x10,
* The extended lba format is supported, metadata is transferred as
* a contiguous part of the logical block that it is associated with.
*/
NVME_NS_EXTENDED_LBA_SUPPORTED = 0x20,
};
* @brief Namespace information
*/
struct nvme_ns_stat {
* Namespace ID.
*/
unsigned int id;
* Namespace command support flags.
*/
enum nvme_ns_flags flags;
* Namespace sector size in bytes.
*/
size_t sector_size;
* Namespace number of sectors.
*/
uint64_t sectors;
* Namespace metadata size in bytes.
*/
size_t md_size;
* Namespace priority information type.
*/
enum nvme_pi_type pi_type;
};
* @brief Queue pair information
*/
struct nvme_qpair_stat {
* Qpair ID
*/
unsigned int id;
* Qpair number of entries
*/
unsigned int qd;
* Qpair is enabled
*/
bool enabled;
* Qpair priority
*/
unsigned int qprio;
};
* @brief Command completion callback function signature
*
* @param cmd_cb_arg Callback function input argument.
* @param cpl_status Contains the completion status.
*/
typedef void (*nvme_cmd_cb)(void *cmd_cb_arg,
const struct nvme_cpl *cpl_status);
* @brief Asynchronous error request completion callback
*
* @param aer_cb_arg AER context set by nvme_register_aer_callback()
* @param cpl_status Completion status of the asynchronous event request
*/
typedef void (*nvme_aer_cb)(void *aer_cb_arg,
const struct nvme_cpl *cpl_status);
* @brief Restart SGL walk to the specified offset callback
*
* @param cb_arg Value passed to nvme_readv/nvme_writev
* @param offset Offset in the SGL
*/
typedef void (*nvme_req_reset_sgl_cb)(void *cb_arg, uint32_t offset);
* @brief Get an SGL entry address and length and advance to the next entry
*
* @param cb_arg Value passed to readv/writev
* @param address Physical address of this segment
* @param length Length of this physical segment
*
* Fill out address and length with the current SGL entry and advance
* to the next entry for the next time the callback is invoked
*/
typedef int (*nvme_req_next_sge_cb)(void *cb_arg,
uint64_t *address, uint32_t *length);
* @brief Open an NVMe controller
*
* @param url PCI device URL
* @param opts controller options
*
* Obtain a handle for an NVMe controller specified as a PCI device URL,
* e.g. pci://[DDDD:]BB:DD.F. If called more than once for the same
* controller, NULL is returned.
* To stop using the the controller and release its associated resources,
* call nvme_ctrlr_close() with the handle returned by this function.
*
* @return A handle to the controller on success and NULL on failure.
*/
struct pci_device {
uint16_t vendor_id;
uint16_t device_id;
uint16_t subvendor_id;
uint16_t subdevice_id;
uint16_t domain;
uint16_t bus;
uint16_t dev;
uint16_t func;
void* pci_info;
};
extern struct nvme_ctrlr * nvme_ctrlr_open(struct pci_device *pdev,
struct nvme_ctrlr_opts *opts);
* @brief Close an open NVMe controller
*
* @param ctrlr Controller handle
*
* This function should be called while no other threads
* are actively using the controller.
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_ctrlr_close(struct nvme_ctrlr *ctrlr);
* @brief Get controller capabilities and features
*
* @param ctrlr Controller handle
* @param cstat Controller information
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_ctrlr_stat(struct nvme_ctrlr *ctrlr,
struct nvme_ctrlr_stat *cstat);
* @brief Get controller data and some data from the capabilities register
*
* @param ctrlr Controller handle
* @param cdata Controller data to fill
* @param rdata Capabilities register data to fill
*
* cdata and rdata are optional (NULL can be specified).
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_ctrlr_data(struct nvme_ctrlr *ctrlr,
struct nvme_ctrlr_data *cdata,
struct nvme_register_data *rdata);
* @brief Get a specific feature of a controller
*
* @param ctrlr Controller handle
* @param sel Feature selector
* @param feature Feature identifier
* @param cdw11 Command word 11 (command dependent)
* @param attributes Features attributes
*
* This function is thread safe and can be called at any point while
* the controller is attached.
*
* @return 0 on success and a negative error code on failure.
*
* See nvme_ctrlr_set_feature()
*/
extern int nvme_ctrlr_get_feature(struct nvme_ctrlr *ctrlr,
enum nvme_feat_sel sel,
enum nvme_feat feature,
uint32_t cdw11, uint32_t *attributes);
* @brief Set a specific feature of a controller
*
* @param ctrlr Controller handle
* @param save Save feature across power cycles
* @param feature Feature identifier
* @param cdw11 Command word 11 (feature dependent)
* @param cdw12 Command word 12 (feature dependent)
* @param attributes Features attributes
*
* This function is thread safe and can be called at any point while
* the controller is attached to the NVMe driver.
*
* @return 0 on success and a negative error code on failure.
*
* See nvme_ctrlr_get_feature()
*/
extern int nvme_ctrlr_set_feature(struct nvme_ctrlr *ctrlr,
bool save, enum nvme_feat feature,
uint32_t cdw11, uint32_t cdw12,
void *buf, uint32_t len,
uint32_t *attributes);
* @brief Attach the specified namespace to controllers
*
* @param ctrlr Controller handle to use for command submission
* @param nsid Namespace ID of the namespaces to attach
* @param clist List of controllers as defined in the NVMe specification
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_ctrlr_attach_ns(struct nvme_ctrlr *ctrlr, unsigned int nsid,
struct nvme_ctrlr_list *clist);
* @brief Detach the specified namespace from controllers
*
* @param ctrlr Controller handle to use for command submission
* @param nsid Namespace ID of the namespaces to detach
* @param clist List of controllers as defined in the NVMe specification
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_ctrlr_detach_ns(struct nvme_ctrlr *ctrlr, unsigned int nsid,
struct nvme_ctrlr_list *clist);
* @brief Create a namespace
*
* @param ctrlr Controller handle
* @param nsdata namespace data
*
* @return Namespace ID (>= 1) on success and 0 on failure.
*/
extern unsigned int nvme_ctrlr_create_ns(struct nvme_ctrlr *ctrlr,
struct nvme_ns_data *nsdata);
* @brief Delete a namespace
*
* @param ctrlr Controller handle
* @param nsid ID of the namespace to delete
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_ctrlr_delete_ns(struct nvme_ctrlr *ctrlr, unsigned int nsid);
* @brief Format media
*
* @param ctrlr Controller handle
* @param nsid ID of the namespace to format
* @param format Format information
*
* This function requests a low-level format of the media.
* If nsid is NVME_GLOBAL_NS_TAG, all namspaces attached to the contoller
* are formatted.
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_ctrlr_format_ns(struct nvme_ctrlr *ctrlr,
unsigned int nsid, struct nvme_format *format);
* @brief Download a new firmware image
*
* @param ctrlr Controller handle
* @param fw Firmware data buffer
* @param size Firmware buffer size
* @param slot Firmware image slot to use
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_ctrlr_update_firmware(struct nvme_ctrlr *ctrlr,
void *fw, size_t size, int slot);
* @brief Get an I/O queue pair
*
* @param ctrlr Controller handle
* @param qprio I/O queue pair priority for weighted round robin arbitration
* @param qd I/O queue pair maximum submission queue depth
*
* A queue depth of 0 will result in the maximum hardware defined queue
* depth being used. The use of a queue pair is not thread safe. Applications
* must ensure mutual exclusion access to the queue pair during I/O processing.
*
* @return An I/O queue pair handle on success and NULL in case of failure.
*/
extern struct nvme_qpair * nvme_ioqp_get(struct nvme_ctrlr *ctrlr,
enum nvme_qprio qprio,
unsigned int qd);
* @brief Release an I/O queue pair
*
* @param qpair I/O queue pair handle
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_ioqp_release(struct nvme_qpair *qpair);
* @brief Get information on an I/O queue pair
*
* @param qpair I/O queue pair handle
* @param qpstat I/O queue pair information to fill
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_qpair_stat(struct nvme_qpair *qpair,
struct nvme_qpair_stat *qpstat);
* @brief Submit an NVMe command
*
* @param qpair I/O qpair handle
* @param cmd Command to submit
* @param buf Payload buffer
* @param len Payload buffer length
* @param cb_fn Callback function
* @param cb_arg Argument for the call back function
*
* This is a low level interface for submitting I/O commands directly.
* The validity of the command will not be checked.
*
* When constructing the nvme_command it is not necessary to fill out the PRP
* list/SGL or the CID. The driver will handle both of those for you.
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_ioqp_submit_cmd(struct nvme_qpair *qpair,
struct nvme_cmd *cmd,
void *buf, size_t len,
nvme_cmd_cb cb_fn, void *cb_arg);
* @brief Process I/O command completions
*
* @param qpair I/O queue pair handle
* @param max_completions Maximum number of completions to check
*
* This call is non-blocking, i.e. it only processes completions that are
* ready at the time of this function call. It does not wait for
* outstanding commands to complete.
* For each completed command, the request callback function will
* be called if specified as non-NULL when the request was submitted.
* This function may be called at any point after the command submission
* while the controller is open
*
* @return The number of completions processed (may be 0).
*
* @sa nvme_cmd_cb
*/
extern unsigned int nvme_qpair_poll(struct nvme_qpair *qpair,
unsigned int max_completions);
* @brief Open a name space
*
* @param ctrlr Controller handle
* @param ns_id ID of the name space to open
*
* @return A namspace handle on success or NULL in case of failure.
*/
extern struct nvme_ns *nvme_ns_open(struct nvme_ctrlr *ctrlr,
unsigned int ns_id);
* @brief Close an open name space
*
* @param ns Namspace handle
*
* See nvme_ns_open()
*/
extern int nvme_ns_close(struct nvme_ns *ns);
* @brief Get information on a namespace
*
* @param ns Namespace handle
* @param ns_stat Namespace information
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_stat(struct nvme_ns *ns,
struct nvme_ns_stat *ns_stat);
* @brief Get namespace data
*
* @param ns Namespace handle
* @param nsdata Namespace data
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_data(struct nvme_ns *ns,
struct nvme_ns_data *nsdata);
* @brief Submit a write I/O
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param buffer Physically contiguous data buffer
* @param lba Starting LBA to read from
* @param lba_count Number of LBAs to read
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
* @param io_flags I/O flags (NVME_IO_FLAGS_*)
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_write(struct nvme_ns *ns, struct nvme_qpair *qpair,
void *buffer,
uint64_t lba, uint32_t lba_count,
nvme_cmd_cb cb_fn, void *cb_arg,
unsigned int io_flags);
* @brief Submit a scattered write I/O
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param lba Starting LBA to write to
* @param lba_count Number of LBAs to write
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
* @param io_flags I/O flags (NVME_IO_FLAGS_*)
* @param reset_sgl_fn Reset scattered payload callback
* @param next_sge_fn Scattered payload iteration callback
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_writev(struct nvme_ns *ns, struct nvme_qpair *qpair,
uint64_t lba, uint32_t lba_count,
nvme_cmd_cb cb_fn, void *cb_arg,
unsigned int io_flags,
nvme_req_reset_sgl_cb reset_sgl_fn,
nvme_req_next_sge_cb next_sge_fn);
* @brief Submits a write I/O with metadata
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param payload Data buffer
* @param metadata Metadata payload
* @param lba Starting LBA to write to
* @param lba_count Number of LBAs to write
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
* @param io_flags I/O flags (NVME_IO_FLAGS_*)
* @param apptag_mask Application tag mask
* @param apptag Application tag to use end-to-end protection information
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_write_with_md(struct nvme_ns *ns, struct nvme_qpair *qpair,
void *payload, void *metadata,
uint64_t lba, uint32_t lba_count,
nvme_cmd_cb cb_fn, void *cb_arg,
unsigned int io_flags,
uint16_t apptag_mask, uint16_t apptag);
* @brief Submit a write zeroes I/O
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param lba Starting LBA to write to
* @param lba_count Number of LBAs to write
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
* @param io_flags I/O flags (NVME_IO_FLAGS_*)
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_write_zeroes(struct nvme_ns *ns, struct nvme_qpair *qpair,
uint64_t lba, uint32_t lba_count,
nvme_cmd_cb cb_fn, void *cb_arg,
unsigned int io_flags);
* @brief Submit a read I/O
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param buffer Physically contiguous data buffer
* @param lba Starting LBA to read from
* @param lba_count Number of LBAs to read
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
* @param io_flags I/O flags (NVME_IO_FLAGS_*)
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_read(struct nvme_ns *ns, struct nvme_qpair *qpair,
void *buffer,
uint64_t lba, uint32_t lba_count,
nvme_cmd_cb cb_fn, void *cb_arg,
unsigned int io_flags);
* @brief Submit a scattered read I/O
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param lba Starting LBA to read from
* @param lba_count Number of LBAs to read
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
* @param io_flags I/O flags (NVME_IO_FLAGS_*)
* @param reset_sgl_fn Reset scattered payload callback
* @param next_sge_fn Scattered payload iteration callback
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_readv(struct nvme_ns *ns, struct nvme_qpair *qpair,
uint64_t lba, uint32_t lba_count,
nvme_cmd_cb cb_fn, void *cb_arg,
unsigned int io_flags,
nvme_req_reset_sgl_cb reset_sgl_fn,
nvme_req_next_sge_cb next_sge_fn);
* @brief Submit a read I/O with metadata
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param buffer Data buffer
* @param metadata Metadata payload
* @param lba Starting LBA to read from
* @param lba_count Number of LBAs to read
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
* @param io_flags I/O flags (NVME_IO_FLAGS_*)
* @param apptag_mask Application tag mask
* @param apptag Application tag to use end-to-end protection information
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_read_with_md(struct nvme_ns *ns, struct nvme_qpair *qpair,
void *buffer, void *metadata,
uint64_t lba, uint32_t lba_count,
nvme_cmd_cb cb_fn, void *cb_arg,
unsigned int io_flags,
uint16_t apptag_mask, uint16_t apptag);
* @brief Submit a deallocate command
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param payload List of LBA ranges to deallocate
* @param num_ranges Number of ranges in the list
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
*
* The number of LBA ranges must be at least 1 and at most
* NVME_DATASET_MANAGEMENT_MAX_RANGES.
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_deallocate(struct nvme_ns *ns, struct nvme_qpair *qpair,
void *payload, uint16_t num_ranges,
nvme_cmd_cb cb_fn, void *cb_arg);
* @brief Submit a flush command
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_flush(struct nvme_ns *ns, struct nvme_qpair *qpair,
nvme_cmd_cb cb_fn, void *cb_arg);
* @brief Submit a reservation register command
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param payload Reservation register data buffer
* @param ignore_key Enable or not the current reservation key check
* @param action Registration action
* @param cptpl Persist Through Power Loss state
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_reservation_register(struct nvme_ns *ns,
struct nvme_qpair *qpair,
struct nvme_reservation_register_data *payload,
bool ignore_key,
enum nvme_reservation_register_action action,
enum nvme_reservation_register_cptpl cptpl,
nvme_cmd_cb cb_fn, void *cb_arg);
* @brief Submit a reservation release command
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param payload Current reservation key buffer
* @param ignore_key Enable or not the current reservation key check
* @param action Reservation release action
* @param type Reservation type
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_reservation_release(struct nvme_ns *ns,
struct nvme_qpair *qpair,
struct nvme_reservation_key_data *payload,
bool ignore_key,
enum nvme_reservation_release_action action,
enum nvme_reservation_type type,
nvme_cmd_cb cb_fn, void *cb_arg);
* @brief Submit a reservation acquire command
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param payload Reservation acquire data buffer
* @param ignore_key Enable or not the current reservation key check
* @param action Reservation acquire action
* @param type Reservation type
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_reservation_acquire(struct nvme_ns *ns,
struct nvme_qpair *qpair,
struct nvme_reservation_acquire_data *payload,
bool ignore_key,
enum nvme_reservation_acquire_action action,
enum nvme_reservation_type type,
nvme_cmd_cb cb_fn, void *cb_arg);
* @brief Submits a reservation report to a namespace
*
* @param ns Namespace handle
* @param qpair I/O queue pair handle
* @param payload Reservation status data buffer
* @param len Length in bytes of the reservation status data
* @param cb_fn Completion callback
* @param cb_arg Argument to pass to the completion callback
*
* The command is submitted to a qpair allocated by nvme_ctrlr_alloc_io_qpair().
* The user must ensure that only one thread submits I/O on
* a given qpair at any given time.
*
* @return 0 on success and a negative error code in case of failure.
*/
extern int nvme_ns_reservation_report(struct nvme_ns *ns,
struct nvme_qpair *qpair,
void *payload, size_t len,
nvme_cmd_cb cb_fn, void *cb_arg);
* Any NUMA node.
*/
#define NVME_NODE_ID_ANY (~0U)
* @brief Allocate physically contiguous memory
*
* @param size Size (in bytes) to be allocated
* @param align Memory alignment constraint
* @param node_id The NUMA node to get memory from or NVME_NODE_ID_ANY
*
* This function allocates memory from the hugepage area of memory. The
* memory is not cleared. In NUMA systems, the memory allocated resides
* on the requested NUMA node if node_id is not NVME_NODE_ID_ANY.
* Otherwise, allocation will take preferrably on the node of the
* function call context, or any other node if that fails.
*
* @return The address of the allocated memory on success and NULL on failure.
*/
extern void *nvme_malloc_node(size_t size, size_t align,
unsigned int node_id);
* @brief Allocate zero'ed memory
*
* @param size Size (in bytes) to be allocated
* @param align Memory alignment constraint
* @param node_id The NUMA node to get memory from or NVME_NODE_ID_ANY
*
* See @nvme_malloc_node.
*/
static inline void *nvme_zmalloc_node(size_t size, size_t align,
unsigned int node_id)
{
void *buf;
buf = nvme_malloc_node(size, align, node_id);
if (buf)
memset(buf, 0, size);
return buf;
}
* @brief Allocate zero'ed array memory
*
* @param num Size of the array
* @param size Size (in bytes) of the array elements
* @param align Memory alignment constraint
* @param node_id The NUMA node to get memory from or NVME_NODE_ID_ANY
*
* See @nvme_malloc_node.
*/
static inline void *nvme_calloc_node(size_t num, size_t size,
size_t align, unsigned int node_id)
{
return nvme_zmalloc_node(size * num, align, node_id);
}
* @brief Allocate physically contiguous memory
*
* @param size Size (in bytes) to be allocated
* @param align Memory alignment constraint
*
* @return The address of the allocated memory on success and NULL on error
*
* See @nvme_malloc_node.
*/
static inline void *nvme_malloc(size_t size, size_t align)
{
return nvme_malloc_node(size, align, NVME_NODE_ID_ANY);
}
* @brief Allocate zero'ed memory
*
* @param size Size (in bytes) to be allocated
* @param align Memory alignment constraint
*
* @return The address of the allocated memory on success and NULL on error
*
* See @nvme_zmalloc_node.
*/
static inline void *nvme_zmalloc(size_t size, size_t align)
{
return nvme_zmalloc_node(size, align, NVME_NODE_ID_ANY);
}
* @brief Allocate zero'ed array memory
*
* @param num Size of the array
* @param size Size (in bytes) of the array elements
* @param align Memory alignment constraint
*
* See @nvme_calloc_node.
*/
static inline void *nvme_calloc(size_t num, size_t size, size_t align)
{
return nvme_calloc_node(num, size, align, NVME_NODE_ID_ANY);
}
* @brief Free allocated memory
*
* @param addr Address of the memory to free
*
* Free the memory at the specified address.
* The address must be one that was returned by one of the
* allocation function nvme_malloc_node(), nvme_zmalloc_node()
* or nvme_calloc_node().
*
* If the pointer is NULL, the function does nothing.
*/
extern void nvme_free(void *addr);
* Structure to hold memory statistics.
*/
struct nvme_mem_stats {
* Number of huge pages allocated.
*/
size_t nr_hugepages;
* Total bytes in memory pools.
*/
size_t total_bytes;
* Total free bytes in memory pools.
*/
size_t free_bytes;
};
* @brief Get memory usage information
*
* @param stats Memory usage inforamtion structure to fill
* @param node_id NUMA node ID or NVME_NVME_NODE_ID_ANY
*
* Return memory usage statistics for the specified
* NUMA node (CPU socket) or global memory usage if node_id
* is NVME_NODE_ID_ANY.
*
* @return 0 on success and a negative error code on failure.
*/
extern int nvme_memstat(struct nvme_mem_stats *stats,
unsigned int node_id);
* @}
*/
#ifdef __cplusplus
}
#endif
#endif