]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
linux: move linux specific stuff from util.{c,h}
authorKlaus Jensen <k.jensen@samsung.com>
Wed, 29 Sep 2021 18:20:23 +0000 (20:20 +0200)
committerKlaus Jensen <k.jensen@samsung.com>
Tue, 19 Oct 2021 20:23:02 +0000 (22:23 +0200)
Add the nvme/linux.h header for Linux specific helpers. This leaves
util.{c,h} with only system-agnostic utilities.

Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
src/Makefile
src/libnvme.h
src/meson.build
src/nvme/fabrics.c
src/nvme/fabrics.h
src/nvme/linux.c [new file with mode: 0644]
src/nvme/linux.h [new file with mode: 0644]
src/nvme/tree.c
src/nvme/util.c
src/nvme/util.h

index 2f269e434337cc29a8b2707d3a76afd8898ab8b9..23372b0b3e424844bb008e72980948bc9d2c725a 100644 (file)
@@ -48,8 +48,8 @@ libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs))
 $(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h
 
 libnvme_priv := nvme/private.h
-libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h nvme/log.h
-libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c
+libnvme_api := libnvme.h nvme/types.h nvme/linux.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h nvme/log.h
+libnvme_srcs := nvme/linux.c nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c
 ifeq ($(CONFIG_JSONC),y)
 override LDFLAGS += $(shell pkg-config --libs json-c)
 override CFLAGS += $(shell pkg-config --cflags json-c)
index 00b1211e70194cc06edcadc024194d6b596a8872..6be90581220af44f2023c814e82b8e7410f45793 100644 (file)
@@ -15,6 +15,7 @@ extern "C" {
 #endif
 
 #include "nvme/types.h"
+#include "nvme/linux.h"
 #include "nvme/ioctl.h"
 #include "nvme/fabrics.h"
 #include "nvme/filters.h"
index 2b8fa638967411070aa554ebd971ef61b200b13e..10acb15ea98b7f1e9375f810393c71702d508b56 100644 (file)
@@ -10,6 +10,7 @@ sources = [
     'nvme/fabrics.c',
     'nvme/filters.c',
     'nvme/ioctl.c',
+    'nvme/linux.c',
     'nvme/log.c',
     'nvme/tree.c',
     'nvme/util.c',
index 21dec686f407ad8dfec115d209d88be01266b5a2..d96f09e97e9daeb612e1a670d2c1698c970e9ebe 100644 (file)
@@ -29,6 +29,7 @@
 #include <ccan/array_size/array_size.h>
 
 #include "fabrics.h"
+#include "linux.h"
 #include "ioctl.h"
 #include "util.h"
 #include "log.h"
index 10ac2e29a59d135f59de50ea651bbb2857e88d92..9b796be545d1f63463846185d2ef95c5f709ecf0 100644 (file)
@@ -182,4 +182,15 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h,
        struct nvmf_disc_log_entry *e,
        const struct nvme_fabrics_config *defcfg, bool *discover);
 
+/**
+ * nvme_chomp() - Strip trailing white space
+ * &s: String to strip
+ * @l: Maximum length of string
+ */
+static inline void nvme_chomp(char *s, int l)
+{
+       while (l && (s[l] == '\0' || s[l] == ' '))
+               s[l--] = '\0';
+}
+
 #endif /* _LIBNVME_FABRICS_H */
diff --git a/src/nvme/linux.c b/src/nvme/linux.c
new file mode 100644 (file)
index 0000000..90b9b5c
--- /dev/null
@@ -0,0 +1,382 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * This file is part of libnvme.
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors: Keith Busch <keith.busch@wdc.com>
+ *         Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "linux.h"
+#include "tree.h"
+#include "log.h"
+
+static int __nvme_open(const char *name)
+{
+       char *path;
+       int fd, ret;
+
+       ret = asprintf(&path, "%s/%s", "/dev", name);
+       if (ret < 0) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       fd = open(path, O_RDONLY);
+       free(path);
+       return fd;
+}
+
+int nvme_open(const char *name)
+{
+       int ret, fd, id, ns;
+       struct stat stat;
+       bool c;
+
+       ret = sscanf(name, "nvme%dn%d", &id, &ns);
+       if (ret != 1 && ret != 2) {
+               errno = EINVAL;
+               return -1;
+       }
+       c = ret == 1;
+
+       fd = __nvme_open(name);
+       if (fd < 0)
+               return fd;
+
+       ret = fstat(fd, &stat);
+       if (ret < 0)
+               goto close_fd;
+
+       if (c) {
+               if (!S_ISCHR(stat.st_mode)) {
+                       errno = EINVAL;
+                       goto close_fd;
+               }
+       } else if (!S_ISBLK(stat.st_mode)) {
+               errno = EINVAL;
+               goto close_fd;
+       }
+
+       return fd;
+
+close_fd:
+       close(fd);
+       return -1;
+}
+
+int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset,
+                        void *buf)
+{
+       int err = 0;
+
+       while (size > 0) {
+               xfer = MIN(xfer, size);
+               err = nvme_fw_download(fd, offset, xfer, buf);
+               if (err)
+                       break;
+
+               buf += xfer;
+               size -= xfer;
+               offset += xfer;
+       }
+
+       return err;
+}
+
+int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
+                       __u32 xfer_len, __u32 data_len, void *data)
+{
+       __u64 offset = 0, xfer;
+       bool retain = true;
+       void *ptr = data;
+       int ret;
+
+       /*
+        * 4k is the smallest possible transfer unit, so restricting to 4k
+        * avoids having to check the MDTS value of the controller.
+        */
+       do {
+               xfer = data_len - offset;
+               if (xfer > xfer_len)
+                       xfer  = xfer_len;
+
+               /*
+                * Always retain regardless of the RAE parameter until the very
+                * last portion of this log page so the data remains latched
+                * during the fetch sequence.
+                */
+               if (offset + xfer == data_len)
+                       retain = rae;
+
+               ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE,
+                                  NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE,
+                                  NVME_CSI_NVM, xfer, ptr);
+               if (ret)
+                       return ret;
+
+               offset += xfer;
+               ptr += xfer;
+       } while (offset < data_len);
+
+       return 0;
+}
+
+int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
+                     __u32 data_len, void *data)
+{
+       return __nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data);
+}
+
+static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae,
+                                 struct nvme_telemetry_log **buf)
+{
+       static const __u32 xfer = NVME_LOG_TELEM_BLOCK_SIZE;
+
+       struct nvme_telemetry_log *telem;
+       enum nvme_cmd_get_log_lid lid;
+       void *log, *tmp;
+       __u32 size;
+       int err;
+
+       log = malloc(xfer);
+       if (!log) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       if (ctrl) {
+               err = nvme_get_log_telemetry_ctrl(fd, true, 0, xfer, log);
+               lid = NVME_LOG_LID_TELEMETRY_CTRL;
+       } else {
+               lid = NVME_LOG_LID_TELEMETRY_HOST;
+               if (create)
+                       err = nvme_get_log_create_telemetry_host(fd, log);
+               else
+                       err = nvme_get_log_telemetry_host(fd, 0, xfer, log);
+       }
+
+       if (err)
+               goto free;
+
+       telem = log;
+       if (ctrl && !telem->ctrlavail) {
+               *buf = log;
+               return 0;
+       }
+
+       /* dalb3 >= dalb2 >= dalb1 */
+       size = (le16_to_cpu(telem->dalb3) + 1) * xfer;
+       tmp = realloc(log, size);
+       if (!tmp) {
+               errno = ENOMEM;
+               err = -1;
+               goto free;
+       }
+       log = tmp;
+
+       err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, rae, size, (void *)log);
+       if (!err) {
+               *buf = log;
+               return 0;
+       }
+free:
+       free(log);
+       return err;
+}
+
+int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log)
+{
+       return nvme_get_telemetry_log(fd, false, true, rae, log);
+}
+
+int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log)
+{
+       return nvme_get_telemetry_log(fd, false, false, false, log);
+}
+
+int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log)
+{
+       return nvme_get_telemetry_log(fd, true, false, false, log);
+}
+
+int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log)
+{
+       __u32 size = sizeof(struct nvme_lba_status_log);
+       void *buf, *tmp;
+       int err;
+
+       buf = malloc(size);
+       if (!buf)
+               return -1;
+
+       *log = buf;
+       err = nvme_get_log_lba_status(fd, true, 0, size, buf);
+       if (err)
+               goto free;
+
+       size = le32_to_cpu((*log)->lslplen);
+       if (!size)
+               return 0;
+
+       tmp = realloc(buf, size);
+       if (!tmp) {
+               err = -1;
+               goto free;
+       }
+       buf = tmp;
+       *log = buf;
+
+       err = nvme_get_log_page(fd, NVME_NSID_NONE, NVME_LOG_LID_LBA_STATUS,
+                               rae, size, buf);
+       if (!err)
+               return 0;
+
+free:
+       *log = NULL;
+       free(buf);
+       return err;
+}
+
+static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls,
+                             __u16 *ctrlist, bool attach)
+{
+       enum nvme_ns_attach_sel sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH;
+       struct nvme_ctrl_list cntlist = { 0 };
+
+       if (attach)
+               sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH;
+
+       nvme_init_ctrl_list(&cntlist, num_ctrls, ctrlist);
+       return nvme_ns_attach(fd, nsid, sel, &cntlist);
+}
+
+int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls,
+                               __u16 *ctrlist)
+{
+       return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, true);
+}
+
+int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls,
+                               __u16 *ctrlist)
+{
+       return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, false);
+}
+
+int nvme_get_ana_log_len(int fd, size_t *analen)
+{
+       struct nvme_id_ctrl ctrl;
+       int ret;
+
+       ret = nvme_identify_ctrl(fd, &ctrl);
+       if (ret)
+               return ret;
+
+       *analen = sizeof(struct nvme_ana_log) +
+               le32_to_cpu(ctrl.nanagrpid) * sizeof(struct nvme_ana_group_desc) +
+               le32_to_cpu(ctrl.mnan) * sizeof(__le32);
+       return 0;
+}
+
+static int __nvme_set_attr(const char *path, const char *value)
+{
+       int ret, fd;
+
+       fd = open(path, O_WRONLY);
+       if (fd < 0) {
+#if 0
+               nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path,
+                        strerror(errno));
+#endif
+               return -1;
+       }
+       ret = write(fd, value, strlen(value));
+       close(fd);
+       return ret;
+}
+
+int nvme_set_attr(const char *dir, const char *attr, const char *value)
+{
+       char *path;
+       int ret;
+
+       ret = asprintf(&path, "%s/%s", dir, attr);
+       if (ret < 0)
+               return -1;
+
+       ret = __nvme_set_attr(path, value);
+       free(path);
+       return ret;
+}
+
+static char *__nvme_get_attr(const char *path)
+{
+       char value[4096] = { 0 };
+       int ret, fd;
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0) {
+#if 0
+               nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path,
+                        strerror(errno));
+#endif
+               return NULL;
+       }
+
+       ret = read(fd, value, sizeof(value) - 1);
+       close(fd);
+       if (ret < 0 || !strlen(value)) {
+               return NULL;
+       }
+
+       if (value[strlen(value) - 1] == '\n')
+               value[strlen(value) - 1] = '\0';
+       while (strlen(value) > 0 && value[strlen(value) - 1] == ' ')
+               value[strlen(value) - 1] = '\0';
+
+       return strlen(value) ? strdup(value) : NULL;
+}
+
+char *nvme_get_attr(const char *dir, const char *attr)
+{
+       char *path, *value;
+       int ret;
+
+       ret = asprintf(&path, "%s/%s", dir, attr);
+       if (ret < 0)
+               return NULL;
+
+       value = __nvme_get_attr(path);
+       free(path);
+       return value;
+}
+
+char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr)
+{
+       return nvme_get_attr(nvme_subsystem_get_sysfs_dir(s), attr);
+}
+
+char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr)
+{
+       return nvme_get_attr(nvme_ctrl_get_sysfs_dir(c), attr);
+}
+
+char *nvme_get_ns_attr(nvme_ns_t n, const char *attr)
+{
+       return nvme_get_attr(nvme_ns_get_sysfs_dir(n), attr);
+}
+
+char *nvme_get_path_attr(nvme_path_t p, const char *attr)
+{
+       return nvme_get_attr(nvme_path_get_sysfs_dir(p), attr);
+}
diff --git a/src/nvme/linux.h b/src/nvme/linux.h
new file mode 100644 (file)
index 0000000..2a751a1
--- /dev/null
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * This file is part of libnvme.
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors: Keith Busch <keith.busch@wdc.com>
+ *         Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+ */
+#ifndef _LIBNVME_LINUX_H
+#define _LIBNVME_LINUX_H
+
+#include "types.h"
+
+/**
+ * nvme_fw_download_seq() -
+ * @fd:     File descriptor of nvme device
+ * @size:   Total size of the firmware image to transfer
+ * @xfer:   Maximum size to send with each partial transfer
+ * @offset: Starting offset to send with this firmware downlaod
+ * @buf:    Address of buffer containing all or part of the firmware image.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset,
+                        void *buf);
+
+/**
+ * nvme_get_ctrl_telemetry() -
+ * @fd:           File descriptor of nvme device
+ * @rae:   Retain asynchronous events
+ * @log:   On success, set to the value of the allocated and retreived log.
+ *
+ * The total size allocated can be calculated as:
+ *   (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log);
+
+/**
+ * nvme_get_host_telemetry() -
+ * @fd:         File descriptor of nvme device
+ * @log: On success, set to the value of the allocated and retreived log.
+ *
+ * The total size allocated can be calculated as:
+ *   (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_get_host_telemetry(int fd,  struct nvme_telemetry_log **log);
+
+/**
+ * nvme_get_new_host_telemetry() -
+ * @fd:  File descriptor of nvme device
+ * @log: On success, set to the value of the allocated and retreived log.
+ *
+ * The total size allocated can be calculated as:
+ *   (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_get_new_host_telemetry(int fd,  struct nvme_telemetry_log **log);
+
+/**
+ * __nvme_get_log_page() -
+ * @fd:              File descriptor of nvme device
+ * @nsid:     Namespace Identifier, if applicable.
+ * @log_id:   Log Identifier, see &enum nvme_cmd_get_log_lid.
+ * @rae:      Retain asynchronous events
+ * @xfer_len: Max log transfer size per request to split the total.
+ * @data_len: Total length of the log to transfer.
+ * @data:     User address of at least &data_len to store the log.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
+                       __u32 xfer_len, __u32 data_len, void *data);
+
+/**
+ * nvme_get_log_page() -
+ * @fd:              File descriptor of nvme device
+ * @nsid:     Namespace Identifier, if applicable.
+ * @log_id:   Log Identifier, see &enum nvme_cmd_get_log_lid.
+ * @rae:      Retain asynchronous events
+ * @data_len: Total length of the log to transfer.
+ * @data:     User address of at least &data_len to store the log.
+ *
+ * Calls __nvme_get_log_page() with a default 4k transfer length, as that is
+ * guarnateed by the protocol to be a safe transfer size.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
+                     __u32 data_len, void *data);
+
+/**
+ * nvme_get_ana_log_len() - Retreive size of the current ANA log
+ * @fd:                File descriptor of nvme device
+ * @analen:    Pointer to where the length will be set on success
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_get_ana_log_len(int fd, size_t *analen);
+
+/**
+ * nvme_get_lba_status_log() - Retreive the LBA Status log page
+ * @fd:           File descriptor of the nvme device
+ * @rae:   Retain asynchronous events
+ * @log:   On success, set to the value of the allocated and retreived log.
+ */
+int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log);
+
+/**
+ * nvme_namespace_attach_ctrls() - Attach namespace to controller(s)
+ * @fd:                File descriptor of nvme device
+ * @nsid:      Namespace ID to attach
+ * @num_ctrls: Number of controllers in ctrlist
+ * @ctrlist:   List of controller IDs to perform the attach action
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
+
+/**
+ * nvme_namespace_detach_ctrls() - Detach namespace from controller(s)
+ * @fd:                File descriptor of nvme device
+ * @nsid:      Namespace ID to detach
+ * @num_ctrls: Number of controllers in ctrlist
+ * @ctrlist:   List of controller IDs to perform the detach action
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
+
+/**
+ * nvme_open() - Open an nvme controller or namespace device
+ * @name: The basename of the device to open
+ *
+ * This will look for the handle in /dev/ and validate the name and filetype
+ * match linux conventions.
+ *
+ * Return: A file descriptor for the device on a successful open, or -1 with
+ * errno set otherwise.
+ */
+int nvme_open(const char *name);
+
+#endif /* _LIBNVME_LINUX_H */
index fb724c9d24625f90829f2430547c15d46f734396..552496d800d72c30af1a21746b9c5503d833358c 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <ccan/list/list.h>
 #include "ioctl.h"
+#include "linux.h"
 #include "filters.h"
 #include "tree.h"
 #include "filters.h"
index bd82add2186a85c5b0f57be241f0c835fcd98928..3fd78490fa8d1f685dfe76483928a39b61a861ba 100644 (file)
@@ -7,24 +7,12 @@
  *         Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
  */
 
-#include <stddef.h>
-#include <stdlib.h>
-#include <stdio.h>
 #include <string.h>
 #include <errno.h>
-#include <dirent.h>
-#include <libgen.h>
 
-#include <sys/param.h>
-#include <sys/stat.h>
 #include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
 
-#include "filters.h"
 #include "util.h"
-#include "tree.h"
-#include "log.h"
 
 static inline __u8 nvme_generic_status_to_errno(__u16 status)
 {
@@ -346,233 +334,6 @@ const char *nvme_status_to_string(int status, bool fabrics)
        return s;
 }
 
-static int __nvme_open(const char *name)
-{
-       char *path;
-       int fd, ret;
-
-       ret = asprintf(&path, "%s/%s", "/dev", name);
-       if (ret < 0) {
-               errno = ENOMEM;
-               return -1;
-       }
-
-       fd = open(path, O_RDONLY);
-       free(path);
-       return fd;
-}
-
-int nvme_open(const char *name)
-{
-       int ret, fd, id, ns;
-       struct stat stat;
-       bool c;
-
-       ret = sscanf(name, "nvme%dn%d", &id, &ns);
-       if (ret != 1 && ret != 2) {
-               errno = EINVAL;
-               return -1;
-       }
-       c = ret == 1;
-
-       fd = __nvme_open(name);
-       if (fd < 0)
-               return fd;
-
-       ret = fstat(fd, &stat);
-       if (ret < 0)
-               goto close_fd;
-
-       if (c) {
-               if (!S_ISCHR(stat.st_mode)) {
-                       errno = EINVAL;
-                       goto close_fd;
-               }
-       } else if (!S_ISBLK(stat.st_mode)) {
-               errno = EINVAL;
-               goto close_fd;
-       }
-
-       return fd;
-
-close_fd:
-       close(fd);
-       return -1;
-}
-
-int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset,
-                        void *buf)
-{
-       int err = 0;
-
-       while (size > 0) {
-               xfer = MIN(xfer, size);
-               err = nvme_fw_download(fd, offset, xfer, buf);
-               if (err)
-                       break;
-
-               buf += xfer;
-               size -= xfer;
-               offset += xfer;
-       }
-
-       return err;
-}
-
-int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
-                       __u32 xfer_len, __u32 data_len, void *data)
-{
-       __u64 offset = 0, xfer;
-       bool retain = true;
-       void *ptr = data;
-       int ret;
-
-       /*
-        * 4k is the smallest possible transfer unit, so restricting to 4k
-        * avoids having to check the MDTS value of the controller.
-        */
-       do {
-               xfer = data_len - offset;
-               if (xfer > xfer_len)
-                       xfer  = xfer_len;
-
-               /*
-                * Always retain regardless of the RAE parameter until the very
-                * last portion of this log page so the data remains latched
-                * during the fetch sequence.
-                */
-               if (offset + xfer == data_len)
-                       retain = rae;
-
-               ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE,
-                                  NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE,
-                                  NVME_CSI_NVM, xfer, ptr);
-               if (ret)
-                       return ret;
-
-               offset += xfer;
-               ptr += xfer;
-       } while (offset < data_len);
-
-       return 0;
-}
-
-int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
-                     __u32 data_len, void *data)
-{
-       return __nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data);
-}
-
-static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae,
-                                 struct nvme_telemetry_log **buf)
-{
-       static const __u32 xfer = NVME_LOG_TELEM_BLOCK_SIZE;
-
-       struct nvme_telemetry_log *telem;
-       enum nvme_cmd_get_log_lid lid;
-       void *log, *tmp;
-       __u32 size;
-       int err;
-
-       log = malloc(xfer);
-       if (!log) {
-               errno = ENOMEM;
-               return -1;
-       }
-
-       if (ctrl) {
-               err = nvme_get_log_telemetry_ctrl(fd, true, 0, xfer, log);
-               lid = NVME_LOG_LID_TELEMETRY_CTRL;
-       } else {
-               lid = NVME_LOG_LID_TELEMETRY_HOST;
-               if (create)
-                       err = nvme_get_log_create_telemetry_host(fd, log);
-               else
-                       err = nvme_get_log_telemetry_host(fd, 0, xfer, log);
-       }
-
-       if (err)
-               goto free;
-
-       telem = log;
-       if (ctrl && !telem->ctrlavail) {
-               *buf = log;
-               return 0;
-       }
-
-       /* dalb3 >= dalb2 >= dalb1 */
-       size = (le16_to_cpu(telem->dalb3) + 1) * xfer;
-       tmp = realloc(log, size);
-       if (!tmp) {
-               errno = ENOMEM;
-               err = -1;
-               goto free;
-       }
-       log = tmp;
-
-       err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, rae, size, (void *)log);
-       if (!err) {
-               *buf = log;
-               return 0;
-       }
-free:
-       free(log);
-       return err;
-}
-
-int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log)
-{
-       return nvme_get_telemetry_log(fd, false, true, rae, log);
-}
-
-int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log)
-{
-       return nvme_get_telemetry_log(fd, false, false, false, log);
-}
-
-int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log)
-{
-       return nvme_get_telemetry_log(fd, true, false, false, log);
-}
-
-int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log)
-{
-       __u32 size = sizeof(struct nvme_lba_status_log);
-       void *buf, *tmp;
-       int err;
-
-       buf = malloc(size);
-       if (!buf)
-               return -1;
-
-       *log = buf;
-       err = nvme_get_log_lba_status(fd, true, 0, size, buf);
-       if (err)
-               goto free;
-
-       size = le32_to_cpu((*log)->lslplen);
-       if (!size)
-               return 0;
-
-       tmp = realloc(buf, size);
-       if (!tmp) {
-               err = -1;
-               goto free;
-       }
-       buf = tmp;
-       *log = buf;
-
-       err = nvme_get_log_page(fd, NVME_NSID_NONE, NVME_LOG_LID_LBA_STATUS,
-                               rae, size, buf);
-       if (!err)
-               return 0;
-
-free:
-       *log = NULL;
-       free(buf);
-       return err;
-}
-
 void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs,
                          __u64 *slbas, __u32 *eilbrts, __u32 *elbatms,
                          __u32 *elbats, __u16 nr)
@@ -623,46 +384,6 @@ void nvme_init_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls,
                cntlist->identifier[i] = cpu_to_le16(ctrlist[i]);
 }
 
-static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls,
-                             __u16 *ctrlist, bool attach)
-{
-       enum nvme_ns_attach_sel sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH;
-       struct nvme_ctrl_list cntlist = { 0 };
-
-       if (attach)
-               sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH;
-
-       nvme_init_ctrl_list(&cntlist, num_ctrls, ctrlist);
-       return nvme_ns_attach(fd, nsid, sel, &cntlist);
-}
-
-int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls,
-                               __u16 *ctrlist)
-{
-       return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, true);
-}
-
-int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls,
-                               __u16 *ctrlist)
-{
-       return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, false);
-}
-
-int nvme_get_ana_log_len(int fd, size_t *analen)
-{
-       struct nvme_id_ctrl ctrl;
-       int ret;
-
-       ret = nvme_identify_ctrl(fd, &ctrl);
-       if (ret)
-               return ret;
-
-       *analen = sizeof(struct nvme_ana_log) +
-               le32_to_cpu(ctrl.nanagrpid) * sizeof(struct nvme_ana_group_desc) +
-               le32_to_cpu(ctrl.mnan) * sizeof(__le32);
-       return 0;
-}
-
 int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len)
 {
        switch (fid) {
@@ -747,96 +468,3 @@ int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype,
                return -EINVAL;
        }
 }
-
-static int __nvme_set_attr(const char *path, const char *value)
-{
-       int ret, fd;
-
-       fd = open(path, O_WRONLY);
-       if (fd < 0) {
-#if 0
-               nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path,
-                        strerror(errno));
-#endif
-               return -1;
-       }
-       ret = write(fd, value, strlen(value));
-       close(fd);
-       return ret;
-}
-
-int nvme_set_attr(const char *dir, const char *attr, const char *value)
-{
-       char *path;
-       int ret;
-
-       ret = asprintf(&path, "%s/%s", dir, attr);
-       if (ret < 0)
-               return -1;
-
-       ret = __nvme_set_attr(path, value);
-       free(path);
-       return ret;
-}
-
-static char *__nvme_get_attr(const char *path)
-{
-       char value[4096] = { 0 };
-       int ret, fd;
-
-       fd = open(path, O_RDONLY);
-       if (fd < 0) {
-#if 0
-               nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path,
-                        strerror(errno));
-#endif
-               return NULL;
-       }
-
-       ret = read(fd, value, sizeof(value) - 1);
-       close(fd);
-       if (ret < 0 || !strlen(value)) {
-               return NULL;
-       }
-
-       if (value[strlen(value) - 1] == '\n')
-               value[strlen(value) - 1] = '\0';
-       while (strlen(value) > 0 && value[strlen(value) - 1] == ' ')
-               value[strlen(value) - 1] = '\0';
-
-       return strlen(value) ? strdup(value) : NULL;
-}
-
-char *nvme_get_attr(const char *dir, const char *attr)
-{
-       char *path, *value;
-       int ret;
-
-       ret = asprintf(&path, "%s/%s", dir, attr);
-       if (ret < 0)
-               return NULL;
-
-       value = __nvme_get_attr(path);
-       free(path);
-       return value;
-}
-
-char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr)
-{
-       return nvme_get_attr(nvme_subsystem_get_sysfs_dir(s), attr);
-}
-
-char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr)
-{
-       return nvme_get_attr(nvme_ctrl_get_sysfs_dir(c), attr);
-}
-
-char *nvme_get_ns_attr(nvme_ns_t n, const char *attr)
-{
-       return nvme_get_attr(nvme_ns_get_sysfs_dir(n), attr);
-}
-
-char *nvme_get_path_attr(nvme_path_t p, const char *attr)
-{
-       return nvme_get_attr(nvme_path_get_sysfs_dir(p), attr);
-}
index b84ccf7a1f91f00c6651d1c512da709b891dedf1..801189558a6d9fc797fa3bca5143e00fbf7eb69b 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef _LIBNVME_UTIL_H
 #define _LIBNVME_UTIL_H
 
-#include "ioctl.h"
+#include "types.h"
 
 /**
  * nvme_status_to_errno() - Converts nvme return status to errno
@@ -31,60 +31,6 @@ __u8 nvme_status_to_errno(int status, bool fabrics);
  */
 const char *nvme_status_to_string(int status, bool fabrics);
 
-/**
- * nvme_fw_download_seq() -
- * @fd:     File descriptor of nvme device
- * @size:   Total size of the firmware image to transfer
- * @xfer:   Maximum size to send with each partial transfer
- * @offset: Starting offset to send with this firmware downlaod
- * @buf:    Address of buffer containing all or part of the firmware image.
- *
- * Return: The nvme command status if a response was received (see
- * &enum nvme_status_field) or -1 with errno set otherwise.
- */
-int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset,
-                        void *buf);
-
-/**
- * nvme_get_ctrl_telemetry() -
- * @fd:           File descriptor of nvme device
- * @rae:   Retain asynchronous events
- * @log:   On success, set to the value of the allocated and retreived log.
- *
- * The total size allocated can be calculated as:
- *   (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE.
- *
- * Return: The nvme command status if a response was received (see
- * &enum nvme_status_field) or -1 with errno set otherwise.
- */
-int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log);
-
-/**
- * nvme_get_host_telemetry() -
- * @fd:         File descriptor of nvme device
- * @log: On success, set to the value of the allocated and retreived log.
- *
- * The total size allocated can be calculated as:
- *   (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE.
- *
- * Return: The nvme command status if a response was received (see
- * &enum nvme_status_field) or -1 with errno set otherwise.
- */
-int nvme_get_host_telemetry(int fd,  struct nvme_telemetry_log **log);
-
-/**
- * nvme_get_new_host_telemetry() -
- * @fd:  File descriptor of nvme device
- * @log: On success, set to the value of the allocated and retreived log.
- *
- * The total size allocated can be calculated as:
- *   (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE.
- *
- * Return: The nvme command status if a response was received (see
- * &enum nvme_status_field) or -1 with errno set otherwise.
- */
-int nvme_get_new_host_telemetry(int fd,  struct nvme_telemetry_log **log);
-
 /**
  * nvme_init_id_ns() - Initialize an Identify Namepsace structure for creation.
  * @ns:              Address of the Identify Namespace structure to initialize
@@ -138,82 +84,6 @@ void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs,
                          __u64 *slbas, __u32 *eilbrts, __u32 *elbatms,
                          __u32 *elbats, __u16 nr);
 
-/**
- * __nvme_get_log_page() -
- * @fd:              File descriptor of nvme device
- * @nsid:     Namespace Identifier, if applicable.
- * @log_id:   Log Identifier, see &enum nvme_cmd_get_log_lid.
- * @rae:      Retain asynchronous events
- * @xfer_len: Max log transfer size per request to split the total.
- * @data_len: Total length of the log to transfer.
- * @data:     User address of at least &data_len to store the log.
- *
- * Return: The nvme command status if a response was received (see
- * &enum nvme_status_field) or -1 with errno set otherwise.
- */
-int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
-                       __u32 xfer_len, __u32 data_len, void *data);
-
-/**
- * nvme_get_log_page() -
- * @fd:              File descriptor of nvme device
- * @nsid:     Namespace Identifier, if applicable.
- * @log_id:   Log Identifier, see &enum nvme_cmd_get_log_lid.
- * @rae:      Retain asynchronous events
- * @data_len: Total length of the log to transfer.
- * @data:     User address of at least &data_len to store the log.
- *
- * Calls __nvme_get_log_page() with a default 4k transfer length, as that is
- * guarnateed by the protocol to be a safe transfer size.
- *
- * Return: The nvme command status if a response was received (see
- * &enum nvme_status_field) or -1 with errno set otherwise.
- */
-int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
-                     __u32 data_len, void *data);
-
-/**
- * nvme_get_ana_log_len() - Retreive size of the current ANA log
- * @fd:                File descriptor of nvme device
- * @analen:    Pointer to where the length will be set on success
- *
- * Return: The nvme command status if a response was received (see
- * &enum nvme_status_field) or -1 with errno set otherwise.
- */
-int nvme_get_ana_log_len(int fd, size_t *analen);
-
-/**
- * nvme_get_lba_status_log() - Retreive the LBA Status log page
- * @fd:           File descriptor of the nvme device
- * @rae:   Retain asynchronous events
- * @log:   On success, set to the value of the allocated and retreived log.
- */
-int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log);
-
-/**
- * nvme_namespace_attach_ctrls() - Attach namespace to controller(s)
- * @fd:                File descriptor of nvme device
- * @nsid:      Namespace ID to attach
- * @num_ctrls: Number of controllers in ctrlist
- * @ctrlist:   List of controller IDs to perform the attach action
- *
- * Return: The nvme command status if a response was received (see
- * &enum nvme_status_field) or -1 with errno set otherwise.
- */
-int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
-
-/**
- * nvme_namespace_detach_ctrls() - Detach namespace from controller(s)
- * @fd:                File descriptor of nvme device
- * @nsid:      Namespace ID to detach
- * @num_ctrls: Number of controllers in ctrlist
- * @ctrlist:   List of controller IDs to perform the detach action
- *
- * Return: The nvme command status if a response was received (see
- * &enum nvme_status_field) or -1 with errno set otherwise.
- */
-int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
-
 /**
  * nvme_get_feature_length() - Retreive the command payload length for a
  *                            specific feature identifier
@@ -239,29 +109,6 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len);
 int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype,
                enum nvme_directive_receive_doper doper, __u32 *len);
 
-/**
- * nvme_open() - Open an nvme controller or namespace device
- * @name: The basename of the device to open
- *
- * This will look for the handle in /dev/ and validate the name and filetype
- * match linux conventions.
- *
- * Return: A file descriptor for the device on a successful open, or -1 with
- * errno set otherwise.
- */
-int nvme_open(const char *name);
-
-/**
- * nvme_chomp() - Strip trailing white space
- * &s: String to strip
- * @l: Maximum length of string
- */
-static inline void nvme_chomp(char *s, int l)
-{
-       while (l && (s[l] == '\0' || s[l] == ' '))
-               s[l--] = '\0';
-}
-
 #define NVME_FEAT_ARB_BURST(v)         NVME_GET(v, FEAT_ARBITRATION_BURST)
 #define NVME_FEAT_ARB_LPW(v)           NVME_GET(v, FEAT_ARBITRATION_LPW)
 #define NVME_FEAT_ARB_MPW(v)           NVME_GET(v, FEAT_ARBITRATION_MPW)