Improve nvmecontrol error reporting.
MFC after: 1 week Sponsored by: iXsystems, Inc.
This commit is contained in:
parent
cc4d36325b
commit
5dc463f9a5
@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "comnd.h"
|
||||
@ -77,7 +78,7 @@ gen_usage(const struct cmd *t)
|
||||
SLIST_FOREACH(walker, &t->subcmd, link) {
|
||||
print_usage(walker);
|
||||
}
|
||||
exit(1);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
int
|
||||
@ -158,7 +159,7 @@ arg_help(int argc __unused, char * const *argv, const struct cmd *f)
|
||||
fprintf(stderr, "%-30.30s - %s\n", buf, opts[i].descr);
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -188,10 +189,10 @@ arg_parse(int argc, char * const * argv, const struct cmd *f)
|
||||
n++;
|
||||
lopts = malloc((n + 2) * sizeof(struct option));
|
||||
if (lopts == NULL)
|
||||
err(1, "option memory");
|
||||
err(EX_OSERR, "option memory");
|
||||
p = shortopts = malloc((2 * n + 3) * sizeof(char));
|
||||
if (shortopts == NULL)
|
||||
err(1, "shortopts memory");
|
||||
err(EX_OSERR, "shortopts memory");
|
||||
idx = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
lopts[i].name = opts[i].long_arg;
|
||||
@ -279,7 +280,7 @@ bad_arg:
|
||||
fprintf(stderr, "Bad value to --%s: %s\n", opts[idx].long_arg, optarg);
|
||||
free(lopts);
|
||||
free(shortopts);
|
||||
exit(1);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -301,7 +302,7 @@ cmd_load_dir(const char *dir __unused, cmd_load_cb_t cb __unused, void *argp __u
|
||||
continue;
|
||||
asprintf(&path, "%s/%s", dir, dent->d_name);
|
||||
if (path == NULL)
|
||||
err(1, "Can't malloc for path, giving up.");
|
||||
err(EX_OSERR, "Can't malloc for path, giving up.");
|
||||
if ((h = dlopen(path, RTLD_NOW | RTLD_GLOBAL)) == NULL)
|
||||
warnx("Can't load %s: %s", path, dlerror());
|
||||
else {
|
||||
|
@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -102,12 +103,14 @@ devlist(const struct cmd *f, int argc, char *argv[])
|
||||
continue;
|
||||
|
||||
found++;
|
||||
read_controller_data(fd, &cdata);
|
||||
if (read_controller_data(fd, &cdata))
|
||||
continue;
|
||||
nvme_strvis(mn, cdata.mn, sizeof(mn), NVME_MODEL_NUMBER_LENGTH);
|
||||
printf("%6s: %s\n", name, mn);
|
||||
|
||||
for (i = 0; i < cdata.nn; i++) {
|
||||
read_namespace_data(fd, i + 1, &nsdata);
|
||||
if (read_namespace_data(fd, i + 1, &nsdata))
|
||||
continue;
|
||||
if (nsdata.nsze == 0)
|
||||
continue;
|
||||
sprintf(name, "%s%d%s%d", NVME_CTRLR_PREFIX, ctrlr,
|
||||
@ -124,7 +127,7 @@ devlist(const struct cmd *f, int argc, char *argv[])
|
||||
|
||||
if (found == 0) {
|
||||
printf("No NVMe controllers found.\n");
|
||||
exit(1);
|
||||
exit(EX_UNAVAILABLE);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -123,9 +124,9 @@ read_image_file(const char *path, void **buf, int32_t *size)
|
||||
*buf = NULL;
|
||||
|
||||
if ((fd = open(path, O_RDONLY)) < 0)
|
||||
err(1, "unable to open '%s'", path);
|
||||
err(EX_NOINPUT, "unable to open '%s'", path);
|
||||
if (fstat(fd, &sb) < 0)
|
||||
err(1, "unable to stat '%s'", path);
|
||||
err(EX_NOINPUT, "unable to stat '%s'", path);
|
||||
|
||||
/*
|
||||
* The NVMe spec does not explicitly state a maximum firmware image
|
||||
@ -139,16 +140,16 @@ read_image_file(const char *path, void **buf, int32_t *size)
|
||||
* a bit.
|
||||
*/
|
||||
if (sb.st_size > INT32_MAX)
|
||||
errx(1, "size of file '%s' is too large (%jd bytes)",
|
||||
errx(EX_USAGE, "size of file '%s' is too large (%jd bytes)",
|
||||
path, (intmax_t)sb.st_size);
|
||||
filesize = (int32_t)sb.st_size;
|
||||
if ((*buf = malloc(filesize)) == NULL)
|
||||
errx(1, "unable to malloc %d bytes", filesize);
|
||||
errx(EX_OSERR, "unable to malloc %d bytes", filesize);
|
||||
if ((*size = read(fd, *buf, filesize)) < 0)
|
||||
err(1, "error reading '%s'", path);
|
||||
err(EX_IOERR, "error reading '%s'", path);
|
||||
/* XXX assuming no short reads */
|
||||
if (*size != filesize)
|
||||
errx(1,
|
||||
errx(EX_IOERR,
|
||||
"error reading '%s' (read %d bytes, requested %d bytes)",
|
||||
path, *size, filesize);
|
||||
close(fd);
|
||||
@ -168,12 +169,12 @@ update_firmware(int fd, uint8_t *payload, int32_t payload_size, uint8_t fwug)
|
||||
if (fwug != 0 && fwug != 0xFF)
|
||||
max_xfer_size = ((uint64_t)fwug << 12);
|
||||
else if (ioctl(fd, NVME_GET_MAX_XFER_SIZE, &max_xfer_size) < 0)
|
||||
err(1, "query max transfer size failed");
|
||||
err(EX_IOERR, "query max transfer size failed");
|
||||
if (max_xfer_size > NVME_MAX_XFER_SIZE)
|
||||
max_xfer_size = NVME_MAX_XFER_SIZE;
|
||||
|
||||
if ((chunk = aligned_alloc(PAGE_SIZE, max_xfer_size)) == NULL)
|
||||
errx(1, "unable to malloc %zd bytes", (size_t)max_xfer_size);
|
||||
errx(EX_OSERR, "unable to malloc %zd bytes", (size_t)max_xfer_size);
|
||||
|
||||
while (resid > 0) {
|
||||
size = (resid >= (int32_t)max_xfer_size) ?
|
||||
@ -189,10 +190,10 @@ update_firmware(int fd, uint8_t *payload, int32_t payload_size, uint8_t fwug)
|
||||
pt.is_read = 0;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "firmware download request failed");
|
||||
err(EX_IOERR, "firmware download request failed");
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "firmware download request returned error");
|
||||
errx(EX_IOERR, "firmware download request returned error");
|
||||
|
||||
resid -= size;
|
||||
off += size;
|
||||
@ -212,7 +213,7 @@ activate_firmware(int fd, int slot, int activate_action)
|
||||
pt.is_read = 0;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "firmware activate request failed");
|
||||
err(EX_IOERR, "firmware activate request failed");
|
||||
|
||||
sct = NVME_STATUS_GET_SCT(pt.cpl.status);
|
||||
sc = NVME_STATUS_GET_SC(pt.cpl.status);
|
||||
@ -222,7 +223,7 @@ activate_firmware(int fd, int slot, int activate_action)
|
||||
return 1;
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "firmware activate request returned error");
|
||||
errx(EX_IOERR, "firmware activate request returned error");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -278,32 +279,33 @@ firmware(const struct cmd *f, int argc, char *argv[])
|
||||
}
|
||||
free(path);
|
||||
|
||||
read_controller_data(fd, &cdata);
|
||||
if (read_controller_data(fd, &cdata))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
oacs_fw = (cdata.oacs >> NVME_CTRLR_DATA_OACS_FIRMWARE_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_FIRMWARE_MASK;
|
||||
|
||||
if (oacs_fw == 0)
|
||||
errx(1,
|
||||
errx(EX_UNAVAILABLE,
|
||||
"controller does not support firmware activate/download");
|
||||
|
||||
fw_slot1_ro = (cdata.frmw >> NVME_CTRLR_DATA_FRMW_SLOT1_RO_SHIFT) &
|
||||
NVME_CTRLR_DATA_FRMW_SLOT1_RO_MASK;
|
||||
|
||||
if (opt.fw_img && opt.slot == 1 && fw_slot1_ro)
|
||||
errx(1, "slot %d is marked as read only", opt.slot);
|
||||
errx(EX_UNAVAILABLE, "slot %d is marked as read only", opt.slot);
|
||||
|
||||
fw_num_slots = (cdata.frmw >> NVME_CTRLR_DATA_FRMW_NUM_SLOTS_SHIFT) &
|
||||
NVME_CTRLR_DATA_FRMW_NUM_SLOTS_MASK;
|
||||
|
||||
if (opt.slot > fw_num_slots)
|
||||
errx(1,
|
||||
errx(EX_UNAVAILABLE,
|
||||
"slot %d specified but controller only supports %d slots",
|
||||
opt.slot, fw_num_slots);
|
||||
|
||||
if (opt.activate && opt.fw_img == NULL &&
|
||||
!slot_has_valid_firmware(fd, opt.slot))
|
||||
errx(1,
|
||||
errx(EX_UNAVAILABLE,
|
||||
"slot %d does not contain valid firmware,\n"
|
||||
"try 'nvmecontrol logpage -p 3 %s' to get a list "
|
||||
"of available images\n",
|
||||
@ -336,7 +338,7 @@ firmware(const struct cmd *f, int argc, char *argv[])
|
||||
if (strncasecmp(prompt, "yes", 3) == 0)
|
||||
break;
|
||||
if (strncasecmp(prompt, "no", 2) == 0)
|
||||
exit(1);
|
||||
exit(EX_DATAERR);
|
||||
printf("Please answer \"yes\" or \"no\". ");
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -159,29 +160,31 @@ format(const struct cmd *f, int argc, char *argv[])
|
||||
free(path);
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
if (((cd.oacs >> NVME_CTRLR_DATA_OACS_FORMAT_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_FORMAT_MASK) == 0)
|
||||
errx(1, "controller does not support format");
|
||||
errx(EX_UNAVAILABLE, "controller does not support format");
|
||||
if (((cd.fna >> NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_SHIFT) &
|
||||
NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_MASK) == 0 && ses == SES_CRYPTO)
|
||||
errx(1, "controller does not support cryptographic erase");
|
||||
errx(EX_UNAVAILABLE, "controller does not support cryptographic erase");
|
||||
|
||||
if (nsid != NVME_GLOBAL_NAMESPACE_TAG) {
|
||||
if (((cd.fna >> NVME_CTRLR_DATA_FNA_FORMAT_ALL_SHIFT) &
|
||||
NVME_CTRLR_DATA_FNA_FORMAT_ALL_MASK) && ses == SES_NONE)
|
||||
errx(1, "controller does not support per-NS format");
|
||||
errx(EX_UNAVAILABLE, "controller does not support per-NS format");
|
||||
if (((cd.fna >> NVME_CTRLR_DATA_FNA_ERASE_ALL_SHIFT) &
|
||||
NVME_CTRLR_DATA_FNA_ERASE_ALL_MASK) && ses != SES_NONE)
|
||||
errx(1, "controller does not support per-NS erase");
|
||||
errx(EX_UNAVAILABLE, "controller does not support per-NS erase");
|
||||
|
||||
/* Try to keep previous namespace parameters. */
|
||||
read_namespace_data(fd, nsid, &nsd);
|
||||
if (read_namespace_data(fd, nsid, &nsd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
if (lbaf < 0)
|
||||
lbaf = (nsd.flbas >> NVME_NS_DATA_FLBAS_FORMAT_SHIFT)
|
||||
& NVME_NS_DATA_FLBAS_FORMAT_MASK;
|
||||
if (lbaf > nsd.nlbaf)
|
||||
errx(1, "LBA format is out of range");
|
||||
errx(EX_USAGE, "LBA format is out of range");
|
||||
if (ms < 0)
|
||||
ms = (nsd.flbas >> NVME_NS_DATA_FLBAS_EXTENDED_SHIFT)
|
||||
& NVME_NS_DATA_FLBAS_EXTENDED_MASK;
|
||||
@ -211,10 +214,10 @@ format(const struct cmd *f, int argc, char *argv[])
|
||||
(ms << 4) + lbaf);
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "format request failed");
|
||||
err(EX_IOERR, "format request failed");
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "format request returned error");
|
||||
errx(EX_IOERR, "format request returned error");
|
||||
close(fd);
|
||||
exit(0);
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -191,7 +192,8 @@ identify_ctrlr(int fd)
|
||||
struct nvme_controller_data cdata;
|
||||
int hexlength;
|
||||
|
||||
read_controller_data(fd, &cdata);
|
||||
if (read_controller_data(fd, &cdata))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
close(fd);
|
||||
|
||||
if (opt.hex) {
|
||||
@ -214,7 +216,8 @@ identify_ns(int fd, uint32_t nsid)
|
||||
struct nvme_namespace_data nsdata;
|
||||
int hexlength;
|
||||
|
||||
read_namespace_data(fd, nsid, &nsdata);
|
||||
if (read_namespace_data(fd, nsid, &nsdata))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
close(fd);
|
||||
|
||||
if (opt.hex) {
|
||||
|
@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/endian.h>
|
||||
|
||||
@ -183,7 +184,7 @@ get_log_buffer(uint32_t size)
|
||||
void *buf;
|
||||
|
||||
if ((buf = malloc(size)) == NULL)
|
||||
errx(1, "unable to malloc %u bytes", size);
|
||||
errx(EX_OSERR, "unable to malloc %u bytes", size);
|
||||
|
||||
memset(buf, 0, size);
|
||||
return (buf);
|
||||
@ -217,7 +218,7 @@ read_logpage(int fd, uint8_t log_page, uint32_t nsid, uint8_t lsp,
|
||||
pt.is_read = 1;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "get log page request failed");
|
||||
err(EX_IOERR, "get log page request failed");
|
||||
|
||||
/* Convert data to host endian */
|
||||
switch (log_page) {
|
||||
@ -259,7 +260,7 @@ read_logpage(int fd, uint8_t log_page, uint32_t nsid, uint8_t lsp,
|
||||
}
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "get log page request returned error");
|
||||
errx(EX_IOERR, "get log page request returned error");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -659,7 +660,7 @@ logpage_help(void)
|
||||
fprintf(stderr, "0x%02x %-10s %s\n", f->log_page, v, f->name);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -697,7 +698,8 @@ logpage(const struct cmd *f, int argc, char *argv[])
|
||||
}
|
||||
free(path);
|
||||
|
||||
read_controller_data(fd, &cdata);
|
||||
if (read_controller_data(fd, &cdata))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
ns_smart = (cdata.lpa >> NVME_CTRLR_DATA_LPA_NS_SMART_SHIFT) &
|
||||
NVME_CTRLR_DATA_LPA_NS_SMART_MASK;
|
||||
@ -709,10 +711,10 @@ logpage(const struct cmd *f, int argc, char *argv[])
|
||||
*/
|
||||
if (nsid != NVME_GLOBAL_NAMESPACE_TAG) {
|
||||
if (opt.page != NVME_LOG_HEALTH_INFORMATION)
|
||||
errx(1, "log page %d valid only at controller level",
|
||||
errx(EX_USAGE, "log page %d valid only at controller level",
|
||||
opt.page);
|
||||
if (ns_smart == 0)
|
||||
errx(1,
|
||||
errx(EX_UNAVAILABLE,
|
||||
"controller does not support per namespace "
|
||||
"smart/health information");
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@ -123,7 +124,8 @@ wdc_append_serial_name(int fd, char *buf, size_t len, const char *suffix)
|
||||
|
||||
len -= strlen(buf);
|
||||
buf += strlen(buf);
|
||||
read_controller_data(fd, &cdata);
|
||||
if (read_controller_data(fd, &cdata))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
memcpy(sn, cdata.sn, NVME_SERIAL_NUMBER_LENGTH);
|
||||
walker = sn + NVME_SERIAL_NUMBER_LENGTH - 1;
|
||||
while (walker > sn && *walker == ' ')
|
||||
@ -151,9 +153,9 @@ wdc_get_data(int fd, uint32_t opcode, uint32_t len, uint32_t off, uint32_t cmd,
|
||||
pt.is_read = 1;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "wdc_get_data request failed");
|
||||
err(EX_IOERR, "wdc_get_data request failed");
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "wdc_get_data request returned error");
|
||||
errx(EX_IOERR, "wdc_get_data request returned error");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -174,7 +176,7 @@ wdc_do_dump_e6(int fd, char *tmpl, const char *suffix, uint32_t opcode,
|
||||
offset = 0;
|
||||
hdr = malloc(len);
|
||||
if (hdr == NULL)
|
||||
errx(1, "Can't get buffer to read dump");
|
||||
errx(EX_OSERR, "Can't get buffer to read dump");
|
||||
wdc_get_data(fd, opcode, len, offset, cmd, hdr, len, false);
|
||||
if (memcmp("E6LG", hdr, 4) == 0) {
|
||||
e6lg_flag = true;
|
||||
@ -183,10 +185,10 @@ wdc_do_dump_e6(int fd, char *tmpl, const char *suffix, uint32_t opcode,
|
||||
/* XXX overwrite protection? */
|
||||
fd2 = open(tmpl, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd2 < 0)
|
||||
err(1, "open %s", tmpl);
|
||||
err(EX_CANTCREAT, "open %s", tmpl);
|
||||
buf = aligned_alloc(PAGE_SIZE, NVME_MAX_XFER_SIZE);
|
||||
if (buf == NULL)
|
||||
errx(1, "Can't get buffer to read dump");
|
||||
errx(EX_OSERR, "Can't get buffer to read dump");
|
||||
offset = 0;
|
||||
len = NVME_MAX_XFER_SIZE;
|
||||
first = 1;
|
||||
@ -198,7 +200,7 @@ wdc_do_dump_e6(int fd, char *tmpl, const char *suffix, uint32_t opcode,
|
||||
if (first) {
|
||||
len = be32dec(buf + len_off);
|
||||
if (len == 0)
|
||||
errx(1, "No data for %s", suffix);
|
||||
errx(EX_PROTOCOL, "No data for %s", suffix);
|
||||
|
||||
printf("Dumping %d bytes of version %d.%d log to %s\n", len,
|
||||
buf[8], buf[9], tmpl);
|
||||
@ -212,7 +214,7 @@ wdc_do_dump_e6(int fd, char *tmpl, const char *suffix, uint32_t opcode,
|
||||
first = 0;
|
||||
}
|
||||
if (write(fd2, buf, resid) != (ssize_t)resid)
|
||||
err(1, "write");
|
||||
err(EX_IOERR, "write");
|
||||
offset += resid;
|
||||
len -= resid;
|
||||
} while (len > 0);
|
||||
@ -238,9 +240,9 @@ wdc_get_data_dui(int fd, uint32_t opcode, uint32_t len, uint64_t off,
|
||||
pt.is_read = 1;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "wdc_get_data_dui request failed");
|
||||
err(EX_IOERR, "wdc_get_data_dui request failed");
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "wdc_get_data_dui request returned error");
|
||||
errx(EX_IOERR, "wdc_get_data_dui request returned error");
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@ -274,7 +276,7 @@ wdc_get_dui_log_size(int fd, uint32_t opcode, uint8_t data_area,
|
||||
len = 1024;
|
||||
hdr = (uint8_t*)malloc(len);
|
||||
if (hdr == NULL)
|
||||
errx(1, "Can't get buffer to read header");
|
||||
errx(EX_OSERR, "Can't get buffer to read header");
|
||||
wdc_get_data_dui(fd, opcode, len, 0, hdr, len);
|
||||
|
||||
hdr += len_off;
|
||||
@ -307,7 +309,7 @@ wdc_get_dui_log_size(int fd, uint32_t opcode, uint8_t data_area,
|
||||
}
|
||||
}
|
||||
else
|
||||
errx(1, "ERROR : No valid header ");
|
||||
errx(EX_PROTOCOL, "ERROR : No valid header ");
|
||||
|
||||
*log_size = dui_size;
|
||||
free(hdr);
|
||||
@ -326,13 +328,13 @@ wdc_do_dump_dui(int fd, char *tmpl, uint8_t data_area,
|
||||
wdc_append_serial_name(fd, tmpl, MAXPATHLEN, suffix);
|
||||
wdc_get_dui_log_size(fd, opcode, data_area, &log_len, len_off);
|
||||
if (log_len == 0)
|
||||
errx(1, "No data for %s", suffix);
|
||||
errx(EX_PROTOCOL, "No data for %s", suffix);
|
||||
fd2 = open(tmpl, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd2 < 0)
|
||||
err(1, "open %s", tmpl);
|
||||
err(EX_CANTCREAT, "open %s", tmpl);
|
||||
buf = aligned_alloc(PAGE_SIZE, NVME_MAX_XFER_SIZE);
|
||||
if (buf == NULL)
|
||||
errx(1, "Can't get buffer to read dump");
|
||||
errx(EX_OSERR, "Can't get buffer to read dump");
|
||||
offset = 0;
|
||||
first = 1;
|
||||
|
||||
@ -347,7 +349,7 @@ wdc_do_dump_dui(int fd, char *tmpl, uint8_t data_area,
|
||||
first = 0;
|
||||
}
|
||||
if (write(fd2, buf, resid) != (ssize_t)resid)
|
||||
err(1, "write");
|
||||
err(EX_IOERR, "write");
|
||||
offset += resid;
|
||||
log_len -= resid;
|
||||
}
|
||||
@ -376,7 +378,8 @@ wdc_cap_diag(const struct cmd *f, int argc, char *argv[])
|
||||
}
|
||||
strlcpy(tmpl, opt.template, sizeof(tmpl));
|
||||
open_dev(opt.dev, &fd, 1, 1);
|
||||
read_controller_data(fd, &cdata);
|
||||
if (read_controller_data(fd, &cdata))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
vid = cdata.vid;
|
||||
|
||||
switch (vid) {
|
||||
@ -390,11 +393,10 @@ wdc_cap_diag(const struct cmd *f, int argc, char *argv[])
|
||||
WDC_NVME_CAP_DIAG_OPCODE_FA, 512);
|
||||
break;
|
||||
default:
|
||||
errx(1, "ERROR : WDC: unsupported device (%#x) for this command", vid);
|
||||
errx(EX_UNAVAILABLE, "ERROR : WDC: unsupported device (%#x) for this command", vid);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -414,12 +415,13 @@ nsactive(const struct cmd *f, int argc, char *argv[])
|
||||
open_dev(path, &fd, 0, 1);
|
||||
}
|
||||
free(path);
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0)
|
||||
errx(1, "controller does not support namespace management");
|
||||
errx(EX_UNAVAILABLE, "controller does not support namespace management");
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc = NVME_OPC_IDENTIFY;
|
||||
@ -429,9 +431,9 @@ nsactive(const struct cmd *f, int argc, char *argv[])
|
||||
pt.len = sizeof(list);
|
||||
pt.is_read = 1;
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "identify request failed");
|
||||
err(EX_IOERR, "identify request failed");
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "identify request returned error");
|
||||
errx(EX_IOERR, "identify request returned error");
|
||||
|
||||
printf("Active namespaces:\n");
|
||||
for (i = 0; list[i] != 0; i++)
|
||||
@ -459,12 +461,13 @@ nsallocated(const struct cmd *f, int argc, char *argv[])
|
||||
open_dev(path, &fd, 0, 1);
|
||||
}
|
||||
free(path);
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0)
|
||||
errx(1, "controller does not support namespace management");
|
||||
errx(EX_UNAVAILABLE, "controller does not support namespace management");
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc = NVME_OPC_IDENTIFY;
|
||||
@ -474,9 +477,9 @@ nsallocated(const struct cmd *f, int argc, char *argv[])
|
||||
pt.len = sizeof(list);
|
||||
pt.is_read = 1;
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "identify request failed");
|
||||
err(EX_IOERR, "identify request failed");
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "identify request returned error");
|
||||
errx(EX_IOERR, "identify request returned error");
|
||||
|
||||
printf("Allocated namespaces:\n");
|
||||
for (i = 0; list[i] != 0; i++)
|
||||
@ -504,12 +507,13 @@ nscontrollers(const struct cmd *f, int argc, char *argv[])
|
||||
open_dev(path, &fd, 0, 1);
|
||||
}
|
||||
free(path);
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0)
|
||||
errx(1, "controller does not support namespace management");
|
||||
errx(EX_UNAVAILABLE, "controller does not support namespace management");
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc = NVME_OPC_IDENTIFY;
|
||||
@ -518,9 +522,9 @@ nscontrollers(const struct cmd *f, int argc, char *argv[])
|
||||
pt.len = sizeof(clist);
|
||||
pt.is_read = 1;
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "identify request failed");
|
||||
err(EX_IOERR, "identify request failed");
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "identify request returned error");
|
||||
errx(EX_IOERR, "identify request returned error");
|
||||
|
||||
n = le16toh(clist[0]);
|
||||
printf("NVM subsystem includes %d controller(s):\n", n);
|
||||
@ -565,12 +569,13 @@ nscreate(const struct cmd *f, int argc, char *argv[])
|
||||
open_dev(path, &fd, 1, 1);
|
||||
}
|
||||
free(path);
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0)
|
||||
errx(1, "controller does not support namespace management");
|
||||
errx(EX_UNAVAILABLE, "controller does not support namespace management");
|
||||
|
||||
/* Allow namespaces sharing if Multi-Path I/O is supported. */
|
||||
if (create_opt.nmic == NONE) {
|
||||
@ -605,10 +610,10 @@ nscreate(const struct cmd *f, int argc, char *argv[])
|
||||
pt.len = sizeof(struct nvme_namespace_data);
|
||||
pt.is_read = 0; /* passthrough writes data to ctrlr */
|
||||
if ((result = ioctl(fd, NVME_PASSTHROUGH_CMD, &pt)) < 0)
|
||||
errx(1, "ioctl request to %s failed: %d", create_opt.dev, result);
|
||||
errx(EX_IOERR, "ioctl request to %s failed: %d", create_opt.dev, result);
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl)) {
|
||||
errx(1, "namespace creation failed: %s",
|
||||
errx(EX_IOERR, "namespace creation failed: %s",
|
||||
get_res_str((pt.cpl.status >> NVME_STATUS_SC_SHIFT) &
|
||||
NVME_STATUS_SC_MASK));
|
||||
}
|
||||
@ -642,12 +647,13 @@ nsdelete(const struct cmd *f, int argc, char *argv[])
|
||||
if (delete_opt.nsid != NONE)
|
||||
nsid = delete_opt.nsid;
|
||||
free(path);
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0)
|
||||
errx(1, "controller does not support namespace management");
|
||||
errx(EX_UNAVAILABLE, "controller does not support namespace management");
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc = NVME_OPC_NAMESPACE_MANAGEMENT;
|
||||
@ -658,10 +664,10 @@ nsdelete(const struct cmd *f, int argc, char *argv[])
|
||||
pt.cmd.nsid = nsid;
|
||||
|
||||
if ((result = ioctl(fd, NVME_PASSTHROUGH_CMD, &pt)) < 0)
|
||||
errx(1, "ioctl request to %s failed: %d", delete_opt.dev, result);
|
||||
errx(EX_IOERR, "ioctl request to %s failed: %d", delete_opt.dev, result);
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl)) {
|
||||
errx(1, "namespace deletion failed: %s",
|
||||
errx(EX_IOERR, "namespace deletion failed: %s",
|
||||
get_res_str((pt.cpl.status >> NVME_STATUS_SC_SHIFT) &
|
||||
NVME_STATUS_SC_MASK));
|
||||
}
|
||||
@ -708,12 +714,13 @@ nsattach(const struct cmd *f, int argc, char *argv[])
|
||||
}
|
||||
if (attach_opt.nsid != NONE)
|
||||
nsid = attach_opt.nsid;
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0)
|
||||
errx(1, "controller does not support namespace management");
|
||||
errx(EX_UNAVAILABLE, "controller does not support namespace management");
|
||||
|
||||
if (attach_opt.ctrlrid == NONE) {
|
||||
/* Get full list of controllers to attach to. */
|
||||
@ -724,9 +731,9 @@ nsattach(const struct cmd *f, int argc, char *argv[])
|
||||
pt.len = sizeof(clist);
|
||||
pt.is_read = 1;
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "identify request failed");
|
||||
err(EX_IOERR, "identify request failed");
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "identify request returned error");
|
||||
errx(EX_IOERR, "identify request returned error");
|
||||
} else {
|
||||
/* By default attach to this controller. */
|
||||
if (attach_opt.ctrlrid == NONE - 1)
|
||||
@ -744,10 +751,10 @@ nsattach(const struct cmd *f, int argc, char *argv[])
|
||||
pt.len = sizeof(clist);
|
||||
|
||||
if ((result = ioctl(fd, NVME_PASSTHROUGH_CMD, &pt)) < 0)
|
||||
errx(1, "ioctl request to %s failed: %d", attach_opt.dev, result);
|
||||
errx(EX_IOERR, "ioctl request to %s failed: %d", attach_opt.dev, result);
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl)) {
|
||||
errx(1, "namespace attach failed: %s",
|
||||
errx(EX_IOERR, "namespace attach failed: %s",
|
||||
get_res_str((pt.cpl.status >> NVME_STATUS_SC_SHIFT) &
|
||||
NVME_STATUS_SC_MASK));
|
||||
}
|
||||
@ -779,12 +786,13 @@ nsdetach(const struct cmd *f, int argc, char *argv[])
|
||||
}
|
||||
if (detach_opt.nsid != NONE)
|
||||
nsid = detach_opt.nsid;
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0)
|
||||
errx(1, "controller does not support namespace management");
|
||||
errx(EX_UNAVAILABLE, "controller does not support namespace management");
|
||||
|
||||
if (detach_opt.ctrlrid == NONE) {
|
||||
/* Get list of controllers this namespace attached to. */
|
||||
@ -796,9 +804,9 @@ nsdetach(const struct cmd *f, int argc, char *argv[])
|
||||
pt.len = sizeof(clist);
|
||||
pt.is_read = 1;
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "identify request failed");
|
||||
err(EX_IOERR, "identify request failed");
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "identify request returned error");
|
||||
errx(EX_IOERR, "identify request returned error");
|
||||
if (clist[0] == 0) {
|
||||
detach_opt.ctrlrid = cd.ctrlr_id;
|
||||
memset(&clist, 0, sizeof(clist));
|
||||
@ -822,10 +830,10 @@ nsdetach(const struct cmd *f, int argc, char *argv[])
|
||||
pt.len = sizeof(clist);
|
||||
|
||||
if ((result = ioctl(fd, NVME_PASSTHROUGH_CMD, &pt)) < 0)
|
||||
errx(1, "ioctl request to %s failed: %d", detach_opt.dev, result);
|
||||
errx(EX_IOERR, "ioctl request to %s failed: %d", detach_opt.dev, result);
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl)) {
|
||||
errx(1, "namespace detach failed: %s",
|
||||
errx(EX_IOERR, "namespace detach failed: %s",
|
||||
get_res_str((pt.cpl.status >> NVME_STATUS_SC_SHIFT) &
|
||||
NVME_STATUS_SC_MASK));
|
||||
}
|
||||
@ -857,12 +865,13 @@ nsattached(const struct cmd *f, int argc, char *argv[])
|
||||
}
|
||||
if (attached_opt.nsid != NONE)
|
||||
nsid = attached_opt.nsid;
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0)
|
||||
errx(1, "controller does not support namespace management");
|
||||
errx(EX_UNAVAILABLE, "controller does not support namespace management");
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc = NVME_OPC_IDENTIFY;
|
||||
@ -872,9 +881,9 @@ nsattached(const struct cmd *f, int argc, char *argv[])
|
||||
pt.len = sizeof(clist);
|
||||
pt.is_read = 1;
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "identify request failed");
|
||||
err(EX_IOERR, "identify request failed");
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "identify request returned error");
|
||||
errx(EX_IOERR, "identify request returned error");
|
||||
|
||||
n = le16toh(clist[0]);
|
||||
printf("Attached %d controller(s):\n", n);
|
||||
@ -910,12 +919,13 @@ nsidentify(const struct cmd *f, int argc, char *argv[])
|
||||
}
|
||||
if (identify_opt.nsid != NONE)
|
||||
nsid = identify_opt.nsid;
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) &
|
||||
NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0)
|
||||
errx(1, "controller does not support namespace management");
|
||||
errx(EX_UNAVAILABLE, "controller does not support namespace management");
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc = NVME_OPC_IDENTIFY;
|
||||
@ -926,10 +936,10 @@ nsidentify(const struct cmd *f, int argc, char *argv[])
|
||||
pt.is_read = 1;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "identify request failed");
|
||||
err(EX_IOERR, "identify request failed");
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "identify request returned error");
|
||||
errx(EX_IOERR, "identify request returned error");
|
||||
|
||||
close(fd);
|
||||
|
||||
@ -939,7 +949,7 @@ nsidentify(const struct cmd *f, int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
if (i == sizeof(nsdata))
|
||||
errx(1, "namespace %d is not allocated", nsid);
|
||||
errx(EX_UNAVAILABLE, "namespace %d is not allocated", nsid);
|
||||
|
||||
/* Convert data to host endian */
|
||||
nvme_namespace_data_swapbytes(&nsdata);
|
||||
|
@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -96,7 +97,7 @@ print_hex(void *data, uint32_t length)
|
||||
print_bytes(data, length);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
read_controller_data(int fd, struct nvme_controller_data *cdata)
|
||||
{
|
||||
struct nvme_pt_command pt;
|
||||
@ -109,16 +110,17 @@ read_controller_data(int fd, struct nvme_controller_data *cdata)
|
||||
pt.is_read = 1;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "identify request failed");
|
||||
return (errno);
|
||||
|
||||
/* Convert data to host endian */
|
||||
nvme_controller_data_swapbytes(cdata);
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "identify request returned error");
|
||||
return (EIO);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata)
|
||||
{
|
||||
struct nvme_pt_command pt;
|
||||
@ -132,13 +134,14 @@ read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata)
|
||||
pt.is_read = 1;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "identify request failed");
|
||||
return (errno);
|
||||
|
||||
/* Convert data to host endian */
|
||||
nvme_namespace_data_swapbytes(nsdata);
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "identify request returned error");
|
||||
return (EIO);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -150,7 +153,7 @@ open_dev(const char *str, int *fd, int write, int exit_on_error)
|
||||
*fd = open(full_path, write ? O_RDWR : O_RDONLY);
|
||||
if (*fd < 0) {
|
||||
if (exit_on_error) {
|
||||
err(1, "could not open %s%s", full_path,
|
||||
err(EX_OSFILE, "could not open %s%s", full_path,
|
||||
write ? " for write" : "");
|
||||
} else
|
||||
return (errno);
|
||||
@ -165,7 +168,7 @@ get_nsid(int fd, char **ctrlr_str, uint32_t *nsid)
|
||||
struct nvme_get_nsid gnsid;
|
||||
|
||||
if (ioctl(fd, NVME_GET_NSID, &gnsid) < 0)
|
||||
err(1, "NVME_GET_NSID ioctl failed");
|
||||
err(EX_OSERR, "NVME_GET_NSID ioctl failed");
|
||||
if (ctrlr_str != NULL)
|
||||
*ctrlr_str = strndup(gnsid.cdev, sizeof(gnsid.cdev));
|
||||
if (nsid != NULL)
|
||||
|
@ -70,8 +70,8 @@ void logpage_register(struct logpage_function *p);
|
||||
|
||||
int open_dev(const char *str, int *fd, int write, int exit_on_error);
|
||||
void get_nsid(int fd, char **ctrlr_str, uint32_t *nsid);
|
||||
void read_controller_data(int fd, struct nvme_controller_data *cdata);
|
||||
void read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata);
|
||||
int read_controller_data(int fd, struct nvme_controller_data *cdata);
|
||||
int read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata);
|
||||
void print_hex(void *data, uint32_t length);
|
||||
void print_namespace(struct nvme_namespace_data *nsdata);
|
||||
void read_logpage(int fd, uint8_t log_page, uint32_t nsid, uint8_t lsp,
|
||||
|
@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -167,9 +168,9 @@ passthru(const struct cmd *f, int argc, char *argv[])
|
||||
open_dev(opt.dev, &fd, 1, 1);
|
||||
|
||||
if (opt.read && opt.write)
|
||||
errx(1, "need exactly one of --read or --write");
|
||||
errx(EX_USAGE, "need exactly one of --read or --write");
|
||||
if (opt.data_len != 0 && !opt.read && !opt.write)
|
||||
errx(1, "need exactly one of --read or --write");
|
||||
errx(EX_USAGE, "need exactly one of --read or --write");
|
||||
if (*opt.ifn && (ifd = open(opt.ifn, O_RDONLY)) == -1) {
|
||||
warn("open %s", opt.ifn);
|
||||
goto cleanup;
|
||||
@ -183,7 +184,7 @@ passthru(const struct cmd *f, int argc, char *argv[])
|
||||
}
|
||||
#else
|
||||
if (opt.metadata_len != 0)
|
||||
errx(1, "metadata not supported on FreeBSD");
|
||||
errx(EX_UNAVAILABLE, "metadata not supported on FreeBSD");
|
||||
#endif
|
||||
if (opt.data_len) {
|
||||
if (posix_memalign(&data, getpagesize(), opt.data_len)) {
|
||||
@ -244,7 +245,7 @@ passthru(const struct cmd *f, int argc, char *argv[])
|
||||
|
||||
errno = 0;
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "passthrough request failed");
|
||||
err(EX_IOERR, "passthrough request failed");
|
||||
/* XXX report status */
|
||||
if (opt.read) {
|
||||
if (opt.binary)
|
||||
@ -260,7 +261,7 @@ cleanup:
|
||||
if (ifd > -1)
|
||||
close(ifd);
|
||||
if (errno)
|
||||
exit(1);
|
||||
exit(EX_IOERR);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -180,7 +181,7 @@ perftest(const struct cmd *f, int argc, char *argv[])
|
||||
io_test.size = opt.size;
|
||||
open_dev(opt.dev, &fd, 1, 1);
|
||||
if (ioctl(fd, ioctl_cmd, &io_test) < 0)
|
||||
err(1, "ioctl NVME_IO_TEST failed");
|
||||
err(EX_IOERR, "ioctl NVME_IO_TEST failed");
|
||||
|
||||
close(fd);
|
||||
print_perftest(&io_test, opt.perthread);
|
||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -115,10 +116,10 @@ power_set(int fd, int power_val, int workload, int perm)
|
||||
pt.cmd.cdw11 = htole32(power_val | (workload << 5));
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "set feature power mgmt request failed");
|
||||
err(EX_IOERR, "set feature power mgmt request failed");
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "set feature power mgmt request returned error");
|
||||
errx(EX_IOERR, "set feature power mgmt request returned error");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -131,10 +132,10 @@ power_show(int fd)
|
||||
pt.cmd.cdw10 = htole32(NVME_FEAT_POWER_MANAGEMENT);
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "set feature power mgmt request failed");
|
||||
err(EX_IOERR, "set feature power mgmt request failed");
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "set feature power mgmt request returned error");
|
||||
errx(EX_IOERR, "set feature power mgmt request returned error");
|
||||
|
||||
printf("Current Power Mode is %d\n", pt.cpl.cdw0);
|
||||
}
|
||||
@ -164,7 +165,8 @@ power(const struct cmd *f, int argc, char *argv[])
|
||||
free(path);
|
||||
|
||||
if (opt.list) {
|
||||
read_controller_data(fd, &cdata);
|
||||
if (read_controller_data(fd, &cdata))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
power_list(&cdata);
|
||||
goto out;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -70,7 +71,7 @@ reset(const struct cmd *f, int argc, char *argv[])
|
||||
free(path);
|
||||
|
||||
if (ioctl(fd, NVME_RESET_CONTROLLER) < 0)
|
||||
err(1, "reset request to %s failed", opt.dev);
|
||||
err(EX_IOERR, "reset request to %s failed", opt.dev);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -261,10 +262,10 @@ resvacquire(const struct cmd *f, int argc, char *argv[])
|
||||
pt.is_read = 0;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "acquire request failed");
|
||||
err(EX_IOERR, "acquire request failed");
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "acquire request returned error");
|
||||
errx(EX_IOERR, "acquire request returned error");
|
||||
|
||||
close(fd);
|
||||
exit(0);
|
||||
@ -299,10 +300,10 @@ resvregister(const struct cmd *f, int argc, char *argv[])
|
||||
pt.is_read = 0;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "register request failed");
|
||||
err(EX_IOERR, "register request failed");
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "register request returned error");
|
||||
errx(EX_IOERR, "register request returned error");
|
||||
|
||||
close(fd);
|
||||
exit(0);
|
||||
@ -336,10 +337,10 @@ resvrelease(const struct cmd *f, int argc, char *argv[])
|
||||
pt.is_read = 0;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "release request failed");
|
||||
err(EX_IOERR, "release request failed");
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "release request returned error");
|
||||
errx(EX_IOERR, "release request returned error");
|
||||
|
||||
close(fd);
|
||||
exit(0);
|
||||
@ -375,10 +376,10 @@ resvreport(const struct cmd *f, int argc, char *argv[])
|
||||
pt.is_read = 1;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "report request failed");
|
||||
err(EX_IOERR, "report request failed");
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "report request returned error");
|
||||
errx(EX_IOERR, "report request returned error");
|
||||
|
||||
close(fd);
|
||||
|
||||
|
@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nvmecontrol.h"
|
||||
@ -154,23 +155,24 @@ sanitize(const struct cmd *f, int argc, char *argv[])
|
||||
goto wait;
|
||||
|
||||
/* Check that controller can execute this command. */
|
||||
read_controller_data(fd, &cd);
|
||||
if (read_controller_data(fd, &cd))
|
||||
errx(EX_IOERR, "Identify request failed");
|
||||
if (((cd.sanicap >> NVME_CTRLR_DATA_SANICAP_BES_SHIFT) &
|
||||
NVME_CTRLR_DATA_SANICAP_BES_MASK) == 0 && sanact == 2)
|
||||
errx(1, "controller does not support Block Erase");
|
||||
errx(EX_UNAVAILABLE, "controller does not support Block Erase");
|
||||
if (((cd.sanicap >> NVME_CTRLR_DATA_SANICAP_OWS_SHIFT) &
|
||||
NVME_CTRLR_DATA_SANICAP_OWS_MASK) == 0 && sanact == 3)
|
||||
errx(1, "controller does not support Overwrite");
|
||||
errx(EX_UNAVAILABLE, "controller does not support Overwrite");
|
||||
if (((cd.sanicap >> NVME_CTRLR_DATA_SANICAP_CES_SHIFT) &
|
||||
NVME_CTRLR_DATA_SANICAP_CES_MASK) == 0 && sanact == 4)
|
||||
errx(1, "controller does not support Crypto Erase");
|
||||
errx(EX_UNAVAILABLE, "controller does not support Crypto Erase");
|
||||
|
||||
/*
|
||||
* If controller supports only one namespace, we may sanitize it.
|
||||
* If there can be more, make user explicit in his commands.
|
||||
*/
|
||||
if (nsid != 0 && cd.nn > 1)
|
||||
errx(1, "can't sanitize one of namespaces, specify controller");
|
||||
errx(EX_UNAVAILABLE, "can't sanitize one of namespaces, specify controller");
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc = NVME_OPC_SANITIZE;
|
||||
@ -179,10 +181,10 @@ sanitize(const struct cmd *f, int argc, char *argv[])
|
||||
pt.cmd.cdw11 = htole32(opt.ovrpat);
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
err(1, "sanitize request failed");
|
||||
err(EX_IOERR, "sanitize request failed");
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
errx(1, "sanitize request returned error");
|
||||
errx(EX_IOERR, "sanitize request returned error");
|
||||
|
||||
wait:
|
||||
read_logpage(fd, NVME_LOG_SANITIZE_STATUS,
|
||||
|
Loading…
x
Reference in New Issue
Block a user