Merge branch 'cleanups'
[unleashed.git] / usr / src / cmd / nvmeadm / nvmeadm_dev.c
blob71c109859ed150f9b10820756c83f45c9d78df2d
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright 2016 Nexenta Systems, Inc.
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <stropts.h>
21 #include <err.h>
22 #include <libdevinfo.h>
23 #include <sys/nvme.h>
24 #include <assert.h>
26 #include "nvmeadm.h"
29 static boolean_t
30 nvme_ioctl(int fd, int ioc, size_t *bufsize, void **buf, uint64_t arg,
31 uint64_t *res)
33 nvme_ioctl_t nioc = { 0 };
35 if (buf != NULL)
36 *buf = NULL;
38 if (res != NULL)
39 *res = ~0ULL;
41 if (bufsize != NULL && *bufsize != 0) {
42 assert(buf != NULL);
44 if ((nioc.n_buf = (uintptr_t)calloc(*bufsize, 1)) == 0)
45 err(-1, "nvme_ioctl()");
47 nioc.n_len = *bufsize;
50 nioc.n_arg = arg;
52 if (ioctl(fd, ioc, &nioc) != 0) {
53 if (debug)
54 warn("nvme_ioctl()");
55 if (nioc.n_buf != 0)
56 free((void *)nioc.n_buf);
58 return (B_FALSE);
61 if (res != NULL)
62 *res = nioc.n_arg;
64 if (bufsize != NULL)
65 *bufsize = nioc.n_len;
67 if (buf != NULL)
68 *buf = (void *)nioc.n_buf;
70 return (B_TRUE);
73 nvme_capabilities_t *
74 nvme_capabilities(int fd)
76 void *cap = NULL;
77 size_t bufsize = sizeof (nvme_capabilities_t);
79 (void) nvme_ioctl(fd, NVME_IOC_CAPABILITIES, &bufsize, &cap, 0, NULL);
81 return (cap);
84 nvme_version_t *
85 nvme_version(int fd)
87 void *vs = NULL;
88 size_t bufsize = sizeof (nvme_version_t);
90 (void) nvme_ioctl(fd, NVME_IOC_VERSION, &bufsize, &vs, 0, NULL);
92 return (vs);
95 nvme_identify_ctrl_t *
96 nvme_identify_ctrl(int fd)
98 void *idctl = NULL;
99 size_t bufsize = NVME_IDENTIFY_BUFSIZE;
101 (void) nvme_ioctl(fd, NVME_IOC_IDENTIFY_CTRL, &bufsize, &idctl, 0,
102 NULL);
104 return (idctl);
107 nvme_identify_nsid_t *
108 nvme_identify_nsid(int fd)
110 void *idns = NULL;
111 size_t bufsize = NVME_IDENTIFY_BUFSIZE;
113 (void) nvme_ioctl(fd, NVME_IOC_IDENTIFY_NSID, &bufsize, &idns, 0, NULL);
115 return (idns);
118 void *
119 nvme_get_logpage(int fd, uint8_t logpage, size_t *bufsize)
121 void *buf = NULL;
123 (void) nvme_ioctl(fd, NVME_IOC_GET_LOGPAGE, bufsize, &buf, logpage,
124 NULL);
126 return (buf);
129 boolean_t
130 nvme_get_feature(int fd, uint8_t feature, uint32_t arg, uint64_t *res,
131 size_t *bufsize, void **buf)
133 return (nvme_ioctl(fd, NVME_IOC_GET_FEATURES, bufsize, buf,
134 (uint64_t)feature << 32 | arg, res));
138 nvme_intr_cnt(int fd)
140 uint64_t res = 0;
142 (void) nvme_ioctl(fd, NVME_IOC_INTR_CNT, NULL, NULL, 0, &res);
143 return ((int)res);
146 boolean_t
147 nvme_format_nvm(int fd, uint8_t lbaf, uint8_t ses)
149 nvme_format_nvm_t frmt = { 0 };
151 frmt.b.fm_lbaf = lbaf & 0xf;
152 frmt.b.fm_ses = ses & 0x7;
154 return (nvme_ioctl(fd, NVME_IOC_FORMAT, NULL, NULL, frmt.r, NULL));
157 boolean_t
158 nvme_detach(int fd)
160 return (nvme_ioctl(fd, NVME_IOC_DETACH, NULL, NULL, 0, NULL));
163 boolean_t
164 nvme_attach(int fd)
166 return (nvme_ioctl(fd, NVME_IOC_ATTACH, NULL, NULL, 0, NULL));
170 nvme_open(di_minor_t minor)
172 char *devpath, *path;
173 int fd;
175 if ((devpath = di_devfs_minor_path(minor)) == NULL)
176 err(-1, "nvme_open()");
178 if (asprintf(&path, "/devices%s", devpath) < 0) {
179 di_devfs_path_free(devpath);
180 err(-1, "nvme_open()");
183 di_devfs_path_free(devpath);
185 fd = open(path, O_RDWR);
186 free(path);
188 if (fd < 0) {
189 if (debug)
190 warn("nvme_open(%s)", path);
191 return (-1);
194 return (fd);
197 void
198 nvme_close(int fd)
200 (void) close(fd);