Index: stable/12/sbin/nvmecontrol/nvmecontrol.8 =================================================================== --- stable/12/sbin/nvmecontrol/nvmecontrol.8 (revision 366859) +++ stable/12/sbin/nvmecontrol/nvmecontrol.8 (revision 366860) @@ -1,528 +1,689 @@ .\" +.\" Copyright (c) 2020 Warner Losh .\" Copyright (c) 2018-2019 Alexander Motin .\" Copyright (c) 2012 Intel Corporation .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions, and the following disclaimer, .\" without modification. .\" 2. Redistributions in binary form must reproduce at minimum a disclaimer .\" substantially similar to the "NO WARRANTY" disclaimer below .\" ("Disclaimer") and any redistribution must be conditioned upon .\" including a substantially similar Disclaimer requirement for further .\" binary redistribution. .\" .\" NO WARRANTY .\" 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 MERCHANTIBILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. .\" .\" nvmecontrol man page. .\" .\" Author: Jim Harris .\" .\" $FreeBSD$ .\" -.Dd August 5, 2019 +.Dd April 30, 2020 .Dt NVMECONTROL 8 .Os .Sh NAME .Nm nvmecontrol .Nd NVM Express control utility .Sh SYNOPSIS .Nm .Ic devlist .Nm .Ic identify .Op Fl v .Op Fl x -.Aq device id -.Aq namespace id +.Op Fl n Ar nsid +.Aq Ar device-id | Ar namespace-id .Nm .Ic perftest .Aq Fl n Ar num_threads .Aq Fl o Ar read|write .Op Fl p .Aq Fl s Ar size_in_bytes .Aq Fl t Ar time_in_sec -.Aq namespace id +.Aq Ar namespace-id .Nm .Ic reset -.Aq controller id +.Aq Ar device-id .Nm .Ic logpage .Aq Fl p Ar page_id .Op Fl x .Op Fl v Ar vendor-string .Op Fl b .Op Fl f Ar LSP .Op Fl i Ar LSI .Op Fl r -.Aq device id -.Aq namespace id +.Aq Ar device-id | Ar namespace-id .Nm .Ic ns active -.Aq device id +.Aq Ar device-id .Nm .Ic ns allocated -.Aq device id +.Aq Ar device-id .Nm .Ic ns attach .Aq Fl n Ar nsid .Aq Fl c Ar cntid -.Aq device id +.Aq Ar device-id .Nm .Ic ns attached .Aq Fl n Ar nsid -.Aq device id +.Aq Ar device-id .Nm .Ic ns controllers -.Aq device id +.Aq Ar device-id .Nm .Ic ns create .Aq Fl s Ar nsze .Op Fl c Ar ncap .Op Fl f Ar lbaf .Op Fl m Ar mset .Op Fl n Ar nmic .Op Fl p Ar pi .Op Fl l Ar pil .Op Fl L Ar flbas .Op Fl d Ar dps -.Aq device id +.Aq Ar device-id .Nm .Ic ns delete .Aq Fl n Ar nsid -.Aq device id +.Aq Ar device-id .Nm .Ic ns detach .Aq Fl n Ar nsid .Aq Fl c Ar cntid -.Aq device id +.Aq Ar device-id .Nm .Ic ns identify .Op Fl v .Op Fl x .Aq Fl n Ar nsid -.Aq device id +.Aq Ar device-id .Nm .Ic nsid -.Aq device id -.Aq namespace id +.Aq Ar device-id | Ar namespace-id .Nm .Ic resv acquire .Aq Fl c Ar crkey .Op Fl p Ar prkey .Aq Fl t Ar rtype .Aq Fl a Ar racqa -.Aq namespace id +.Aq Ar namespace-id .Nm .Ic resv register .Op Fl c Ar crkey .Aq Fl k Ar nrkey .Aq Fl r Ar rrega .Op Fl i Ar iekey .Op Fl p Ar cptpl -.Aq namespace id +.Aq Ar namespace-id .Nm .Ic resv release .Aq Fl c Ar crkey .Aq Fl t Ar rtype .Aq Fl a Ar rrela -.Aq namespace id +.Aq Ar namespace-id .Nm .Ic resv report .Op Fl e .Op Fl v .Op Fl x -.Aq namespace id +.Aq Ar namespace-id .Nm .Ic firmware .Op Fl s Ar slot .Op Fl f Ar path_to_firmware .Op Fl a -.Aq device id +.Aq Ar device-id .Nm .Ic format .Op Fl f Ar fmt .Op Fl m Ar mset .Op Fl o Ar pi .Op Fl l Ar pil .Op Fl E .Op Fl C -.Aq device id -.Aq namespace id +.Aq Ar device-id | Ar namespace-id .Nm .Ic sanitize .Aq Fl a Ar sanact .Op Fl c Ar owpass .Op Fl d .Op Fl p Ar ovrpat .Op Fl r .Op Fl I .Op Fl U -.Aq device id +.Aq Ar device-id .Nm .Ic power .Op Fl l .Op Fl p power_state .Op Fl w workload_hint .Nm .Ic wdc cap-diag .Op Fl o path_template -.Aq device id +.Aq Ar device-id .Nm .Ic wdc drive-log .Op Fl o path_template -.Aq device id +.Aq Ar device-id .Nm .Ic wdc get-crash-dump .Op Fl o path_template -.Aq device id +.Aq Ar device-id .\" .Nm .\" .Ic wdc purge -.\" .Aq device id +.\" .Aq device-id .\" .Nm .\" .Ic wdc purge-monitor -.\" .Aq device id +.\" .Aq device-id +.Nm +.Ic admin-passthru +.Op args +.Aq Ar device-id +.Nm +.Ic io-passthru +.Op args +.Aq Ar namespace-id .Sh DESCRIPTION NVM Express (NVMe) is a storage protocol standard, for SSDs and other high-speed storage devices over PCI Express. .Pp +.Ss identify +The identify commands reports information from the drive's +.Dv IDENTIFY_CONTROLLER +if a +.Ar device-id +is specified. +It reports +.Dv IDENTIFY_NAMESPACE +data if a +.Ar namespace-id +is specified. +When used with disk names, the +.Dv IDENTIFY_NAMESPACE +data is reported, unless the namespace +.Ar nsid +is overridden with the +.Fl n +flag. +Then that namespace's data is reported, if it exists. +The command accepts the following parameters: +.Bl -tag -width 6n +.It Fl n +The namespace +.Aq nsid +to use instead of the namespace associated with the device. +A +.Ar nsid +of +.Dq 0 +is used to retrieve the +.Dv IDENTIFY_CONTROLLER +data associated with that drive. .Ss logpage The logpage command knows how to print log pages of various types. It also knows about vendor specific log pages from hgst/wdc and intel. Note that some vendors use the same log page numbers for different data. .Pp .Bl -tag -compact -width "Page 0x00" .It Dv Page 0x01 Drive Error Log .It Dv Page 0x02 Health/SMART Data .It Dv Page 0x03 Firmware Information .It Dv Page 0x04 Changed Namespace List .It Dv Page 0x05 Commands Supported and Effects .It Dv Page 0x80 Reservation Notification .It Dv Page 0x81 Sanitize Status .It Dv Page 0xc1 Advanced SMART information (WDC/HGST) .It Dv Page 0xc1 Read latency stats (Intel) .It Dv Page 0xc2 Wite latency stats (Intel) .It Dv Page 0xc5 Temperature stats (Intel) .It Dv Page 0xca Advanced SMART information (Intel) .El .Pp Specifying .Fl v .Ic help will list all valid vendors and pages. .Fl x will print the page as hex. .Fl b will print the binary data for the page. .Fl s will set Log Specific Field. .Fl i will set Log Specific Identifier. .Fl r will set Retain Asynchronous Event. .Ss ns Various namespace management commands. If namespace management is supported by device, allow list, create and delete namespaces, list, attach and detach controllers to namespaces. +.Ss nsid +Reports the namespace id and controller device associated with the +.Aq Ar namespace-id +or +.Aq Ar device-id +argument. .Ss resv acquire Acquire or preempt namespace reservation, using specified parameters: .Bl -tag -width 6n .It Fl a Acquire action: .Bl -tag -compact -width 6n .It Dv 0 Acquire .It Dv 1 Preempt .It Dv 2 Preempt and abort .El .It Fl c Current reservation key. .It Fl p Preempt reservation key. .It Fl t Reservation type: .Bl -tag -compact -width 6n .It Dv 1 Write Exclusive .It Dv 2 Exclusive Access .It Dv 3 Write Exclusive - Registrants Only .It Dv 4 Exclusive Access - Registrants Only .It Dv 5 Write Exclusive - All Registrants .It Dv 6 Exclusive Access - All Registrants .El .El .Ss resv register Register, unregister or replace reservation key, using specified parameters: .Bl -tag -width 6n .It Fl c Current reservation key. .It Fl k New reservation key. .It Fl r Register action: .Bl -tag -compact -width 6n .It Dv 0 Register .It Dv 1 Unregister .It Dv 2 Replace .El .It Fl i Ignore Existing Key .It Fl p Change Persist Through Power Loss State: .Bl -tag -compact -width 6n .It Dv 0 No change to PTPL state .It Dv 2 Set PTPL state to ‘0’. Reservations are released and registrants are cleared on a power on. .It Dv 3 Set PTPL state to ‘1’. Reservations and registrants persist across a power loss. .El .El .Ss resv release Release or clear reservation, using specified parameters: .Bl -tag -width 6n .It Fl c Current reservation key. .It Fl t Reservation type. .It Fl a Release action: .Bl -tag -compact -width 6n .It Dv 0 Release .It Dv 1 Clean .El .El .Ss resv report Print reservation status, using specified parameters: .Bl -tag -width 6n .It Fl x Print reservation status in hex. .It Fl e Use Extended Data Structure. .El .Ss format Format either specified namespace, or all namespaces of specified controller, using specified parameters: .Ar fmt LBA Format, .Ar mset Metadata Settings, .Ar pi Protection Information, .Ar pil Protection Information Location. When formatting specific namespace, existing values are used as defaults. When formatting all namespaces, all parameters should be specified. Some controllers may not support formatting or erasing specific or all namespaces. Option .Fl E enables User Data Erase during format. Option .Fl C enables Cryptographic Erase during format. .Ss sanitize Sanitize NVM subsystem of specified controller, using specified parameters: .Bl -tag -width 6n .It Fl a Ar operation Specify the sanitize operation to perform. .Bl -tag -width 16n .It overwrite Perform an overwrite operation by writing a user supplied data pattern to the device one or more times. The pattern is given by the .Fl p argument. The number of times is given by the .Fl c argument. .It block Perform a block erase operation. All the device's blocks are set to a vendor defined value, typically zero. .It crypto Perform a cryptographic erase operation. The encryption keys are changed to prevent the decryption of the data. .It exitfailure Exits a previously failed sanitize operation. A failed sanitize operation can only be exited if it was run in the unrestricted completion mode, as provided by the .Fl U argument. .El .It Fl c Ar passes The number of passes when performing an .Sq overwrite operation. Valid values are between 1 and 16. The default is 1. .It Fl d No Deallocate After Sanitize. .It Fl I When performing an .Sq overwrite operation, the pattern is inverted between consecutive passes. .It Fl p Ar pattern 32 bits of pattern to use when performing an .Sq overwrite operation. The pattern is repeated as needed to fill each block. .It Fl U Perform the sanitize in the unrestricted completion mode. If the operation fails, it can later be exited with the .Sq exitfailure operation. .It Fl r Run in .Dq report only mode. This will report status on a sanitize that is already running on the drive. .El .Ss wdc The various wdc command retrieve log data from the wdc/hgst drives. The .Fl o flag specifies a path template to use to output the files. Each file takes the path template (which defaults to nothing), appends the drive's serial number and the type of dump it is followed by .bin. These logs must be sent to the vendor for analysis. This tool only provides a way to extract them. +.Ss passthru +The +.Dq admin-passthru +and +.Dq io-passthru +commands send NVMe commands to +either the administrative or the data part of the device. +These commands are expected to be compatible with nvme-cli. +Please see +.St The NVMe Standard +for details. +.Bl -tag -width 16n +.It Fl o -opcode Ar opcode +Opcode to send. +.It Fl 2 -cdw2 Ar value +32-bit value for CDW2. +.It Fl 3 -cdw3 Ar value +32-bit value for CDW3. +.It Fl 4 -cdw10 Ar value +32-bit value for CDW10. +.It Fl 5 -cdw11 Ar value +32-bit value for CDW11. +.It Fl 6 -cdw12 Ar value +32-bit value for CDW12. +.It Fl 7 -cdw13 Ar value +32-bit value for CDW13. +.It Fl 8 -cdw14 Ar value +32-bit value for CDW14. +.It Fl 9 -cdw15 Ar value +32-bit value for CDW15. +.It Fl l -data-len +Length of the data for I/O (bytes). +.It Fl m -metadata-len +Length of the metadata segment for command (bytes). +This is ignored and not implemented in +.Xr nvme 4 . +.It Fl f -flags +Nvme command flags. +.It Fl n -namespace-id +Namespace ID for command (Ignored). +.It Fl p -prefill +Value to prefill payload with. +.It Fl b -raw-binary +Output in binary format (otherwise a hex dump is produced). +.It Fl d -dry-run +Do not actually execute the command, but perform sanity checks on it. +.It Fl r -read +Command reads data from the device. +.It Fl s -show-command +Show all the command values on stdout. +.It Fl w -write +Command writes data to the device. +.El +Send arbitrary commands to the device. +Can be used to extract vendor specific logs. +Transfers to/from the device possible, but limited to +.Dv MAXPHYS +bytes. +Commands either read data or write it, but not both. +Commands needing metadata are not supported by the +.Xr nvme 4 +drive. +.Sh DEVICE NAMES +Where +.Aq Ar namespace-id +is required, you can use either the +.Pa nvmeXnsY +device, or the disk device such as +.Pa ndaZ +or +.Pa nvdZ . +The leading +.Pa /dev/ +is omitted. +Where +.Aq Ar device-id +is required, you can use either the +.Pa nvmeX +device, or the disk device such as +.Pa nda Z +or +.Pa nvdZ . +For commands that take an optional +.Aq nsid +you can use it to get information on other namespaces, or to query the +drive itself. +A +.Aq nsid +of +.Dq 0 +means query the drive itself. .Sh EXAMPLES .Dl nvmecontrol devlist .Pp Display a list of NVMe controllers and namespaces along with their device nodes. .Pp .Dl nvmecontrol identify nvme0 +.Dl nvmecontrol identify -n 0 nvd0 .Pp -Display a human-readable summary of the nvme0 IDENTIFY_CONTROLLER data. +Display a human-readable summary of the nvme0 +.Dv IDENTIFY_CONTROLLER +data. +In this example, nvd0 is connected to nvme0. .Pp .Dl nvmecontrol identify -x -v nvme0ns1 +.Dl nvmecontrol identify -x -v -n 1 nvme0 .Pp -Display an hexadecimal dump of the nvme0 IDENTIFY_NAMESPACE data for namespace -1. +Display an hexadecimal dump of the nvme0 +.Dv IDENTIFY_NAMESPACE +data for namespace 1. .Pp .Dl nvmecontrol perftest -n 32 -o read -s 512 -t 30 nvme0ns1 .Pp Run a performance test on nvme0ns1 using 32 kernel threads for 30 seconds. Each thread will issue a single 512 byte read command. Results are printed to stdout when 30 seconds expires. .Pp .Dl nvmecontrol reset nvme0 +.Dl nvmecontrol reset nda4 .Pp Perform a controller-level reset of the nvme0 controller. +In this example, nda4 is wired to nvme0. .Pp .Dl nvmecontrol logpage -p 1 nvme0 .Pp Display a human-readable summary of the nvme0 controller's Error Information Log. Log pages defined by the NVMe specification include Error Information Log (ID=1), SMART/Health Information Log (ID=2), and Firmware Slot Log (ID=3). .Pp .Dl nvmecontrol logpage -p 0xc1 -v wdc nvme0 .Pp Display a human-readable summary of the nvme0's wdc-specific advanced SMART data. .Pp .Dl nvmecontrol logpage -p 1 -x nvme0 .Pp Display a hexadecimal dump of the nvme0 controller's Error Information Log. .Pp .Dl nvmecontrol logpage -p 0xcb -b nvme0 > /tmp/page-cb.bin .Pp Print the contents of vendor specific page 0xcb as binary data on standard out. Redirect it to a temporary file. .Pp .Dl nvmecontrol firmware -s 2 -f /tmp/nvme_firmware nvme0 .Pp Download the firmware image contained in "/tmp/nvme_firmware" to slot 2 of the nvme0 controller, but do not activate the image. .Pp .Dl nvmecontrol firmware -s 4 -a nvme0 .Pp Activate the firmware in slot 4 of the nvme0 controller on the next reset. .Pp .Dl nvmecontrol firmware -s 7 -f /tmp/nvme_firmware -a nvme0 .Pp Download the firmware image contained in "/tmp/nvme_firmware" to slot 7 of the nvme0 controller and activate it on the next reset. .Pp .Dl nvmecontrol power -l nvme0 .Pp List all the current power modes. .Pp .Dl nvmecontrol power -p 3 nvme0 .Pp Set the current power mode. .Pp .Dl nvmecontrol power nvme0 .Pp Get the current power mode. +.Pp +.Dl nvmecontrol identify -n 0 nda0 +.Pp +Identify the drive data associated with the +.Pa nda0 +device. +The corresponding +.Pa nvmeX +devices is used automatically. +.Pp +.Dl nvmecontrol identify nda0 +.Pp +Get the namespace parameters associated with the +.Pa nda0 +device. +The corresponding +.Pa nvmeXnsY +device is used automatically. .Sh DYNAMIC LOADING The directories .Pa /lib/nvmecontrol and .Pa /usr/local/lib/nvmecontrol are scanned for any .so files. These files are loaded. The members of the .Va top linker set are added to the top-level commands. The members of the .Va logpage linker set are added to the logpage parsers. .Sh HISTORY The .Nm utility appeared in .Fx 9.2 . .Sh AUTHORS .An -nosplit .Nm was developed by Intel and originally written by .An Jim Harris Aq Mt jimharris@FreeBSD.org . .Pp This man page was written by .An Jim Harris Aq Mt jimharris@FreeBSD.org . Index: stable/12/sbin/nvmecontrol/passthru.c =================================================================== --- stable/12/sbin/nvmecontrol/passthru.c (revision 366859) +++ stable/12/sbin/nvmecontrol/passthru.c (revision 366860) @@ -1,299 +1,299 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (C) 2012-2013 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include "nvmecontrol.h" #include "comnd.h" static struct options { uint8_t opcode; uint8_t flags; uint16_t rsvd; uint32_t nsid; uint32_t data_len; uint32_t metadata_len; uint32_t timeout; uint32_t cdw2; uint32_t cdw3; uint32_t cdw10; uint32_t cdw11; uint32_t cdw12; uint32_t cdw13; uint32_t cdw14; uint32_t cdw15; const char *ifn; bool binary; bool show_command; bool dry_run; bool read; bool write; uint8_t prefill; const char *dev; } opt = { .binary = false, .cdw10 = 0, .cdw11 = 0, .cdw12 = 0, .cdw13 = 0, .cdw14 = 0, .cdw15 = 0, .cdw2 = 0, .cdw3 = 0, .data_len = 0, .dry_run = false, .flags = 0, .ifn = "", .metadata_len = 0, .nsid = 0, .opcode = 0, .prefill = 0, .read = false, .rsvd = 0, .show_command = false, .timeout = 0, .write = false, .dev = NULL, }; /* * Argument names and short names selected to match the nvme-cli program * so vendor-siupplied formulas work out of the box on FreeBSD with a simple * s/nvme/nvmecontrol/. */ #define ARG(l, s, t, opt, addr, desc) { l, s, t, &opt.addr, desc } static struct opts opts[] = { ARG("opcode", 'o', arg_uint8, opt, opcode, "NVMe command opcode (required)"), ARG("cdw2", '2', arg_uint32, opt, cdw2, "Command dword 2 value"), ARG("cdw3", '3', arg_uint32, opt, cdw3, "Command dword 3 value"), ARG("cdw10", '4', arg_uint32, opt, cdw10, "Command dword 10 value"), ARG("cdw11", '5', arg_uint32, opt, cdw11, "Command dword 11 value"), ARG("cdw12", '6', arg_uint32, opt, cdw12, "Command dword 12 value"), ARG("cdw13", '7', arg_uint32, opt, cdw13, "Command dword 13 value"), ARG("cdw14", '8', arg_uint32, opt, cdw14, "Command dword 14 value"), ARG("cdw15", '9', arg_uint32, opt, cdw15, "Command dword 15 value"), ARG("data-len", 'l', arg_uint32, opt, data_len, "Length of data for I/O (bytes)"), ARG("metadata-len", 'm', arg_uint32, opt, metadata_len, "Length of metadata segment (bytes) (igored)"), ARG("flags", 'f', arg_uint8, opt, flags, "NVMe command flags"), ARG("input-file", 'i', arg_path, opt, ifn, "Input file to send (default stdin)"), ARG("namespace-id", 'n', arg_uint32, opt, nsid, "Namespace id (ignored on FreeBSD)"), ARG("prefill", 'p', arg_uint8, opt, prefill, "Value to prefill payload with"), ARG("rsvd", 'R', arg_uint16, opt, rsvd, "Reserved field value"), ARG("timeout", 't', arg_uint32, opt, timeout, "Command timeout (ms)"), ARG("raw-binary", 'b', arg_none, opt, binary, "Output in binary format"), ARG("dry-run", 'd', arg_none, opt, dry_run, "Don't actually execute the command"), ARG("read", 'r', arg_none, opt, read, "Command reads data from device"), ARG("show-command", 's', arg_none, opt, show_command, "Show all the command values on stdout"), ARG("write", 'w', arg_none, opt, write, "Command writes data to device"), { NULL, 0, arg_none, NULL, NULL } }; static const struct args args[] = { { arg_string, &opt.dev, "controller-id|namespace-id" }, { arg_none, NULL, NULL }, }; static void passthru(const struct cmd *f, int argc, char *argv[]) { int fd = -1, ifd = -1; size_t bytes_read; void *data = NULL, *metadata = NULL; struct nvme_pt_command pt; if (arg_parse(argc, argv, f)) return; open_dev(argv[optind], &fd, 1, 1); if (opt.read && opt.write) errx(1, "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"); if (*opt.ifn && (ifd = open(opt.ifn, O_RDONLY)) == -1) { warn("open %s", opt.ifn); goto cleanup; } #if notyet /* No support in kernel for this */ if (opt.metadata_len != 0) { if (posix_memalign(&metadata, getpagesize(), opt.metadata_len)) { warn("can't allocate %d bytes for metadata", metadata_len); goto cleanup; } } #else if (opt.metadata_len != 0) errx(1, "metadata not supported on FreeBSD"); #endif if (opt.data_len) { if (posix_memalign(&data, getpagesize(), opt.data_len)) { warn("can't allocate %d bytes for data", opt.data_len); goto cleanup; } memset(data, opt.prefill, opt.data_len); if (opt.write && (bytes_read = read(ifd, data, opt.data_len)) != opt.data_len) { warn("read %s; expected %u bytes; got %zd", *opt.ifn ? opt.ifn : "stdin", opt.data_len, bytes_read); goto cleanup; } } if (opt.show_command) { fprintf(stderr, "opcode : %#02x\n", opt.opcode); fprintf(stderr, "flags : %#02x\n", opt.flags); fprintf(stderr, "rsvd1 : %#04x\n", opt.rsvd); fprintf(stderr, "nsid : %#04x\n", opt.nsid); fprintf(stderr, "cdw2 : %#08x\n", opt.cdw2); fprintf(stderr, "cdw3 : %#08x\n", opt.cdw3); fprintf(stderr, "data_len : %#08x\n", opt.data_len); fprintf(stderr, "metadata_len : %#08x\n", opt.metadata_len); fprintf(stderr, "data : %p\n", data); fprintf(stderr, "metadata : %p\n", metadata); fprintf(stderr, "cdw10 : %#08x\n", opt.cdw10); fprintf(stderr, "cdw11 : %#08x\n", opt.cdw11); fprintf(stderr, "cdw12 : %#08x\n", opt.cdw12); fprintf(stderr, "cdw13 : %#08x\n", opt.cdw13); fprintf(stderr, "cdw14 : %#08x\n", opt.cdw14); fprintf(stderr, "cdw15 : %#08x\n", opt.cdw15); fprintf(stderr, "timeout_ms : %d\n", opt.timeout); } if (opt.dry_run) { errno = 0; warn("Doing a dry-run, no actual I/O"); goto cleanup; } memset(&pt, 0, sizeof(pt)); pt.cmd.opc = opt.opcode; pt.cmd.fuse = opt.flags; pt.cmd.cid = htole16(opt.rsvd); pt.cmd.nsid = opt.nsid; /* XXX note: kernel overrides this */ pt.cmd.rsvd2 = htole32(opt.cdw2); pt.cmd.rsvd3 = htole32(opt.cdw3); pt.cmd.cdw10 = htole32(opt.cdw10); pt.cmd.cdw11 = htole32(opt.cdw11); pt.cmd.cdw12 = htole32(opt.cdw12); pt.cmd.cdw13 = htole32(opt.cdw13); pt.cmd.cdw14 = htole32(opt.cdw14); pt.cmd.cdw15 = htole32(opt.cdw15); pt.buf = data; pt.len = opt.data_len; pt.is_read = opt.read; errno = 0; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) err(1, "passthrough request failed"); /* XXX report status */ if (opt.read) { if (opt.binary) write(STDOUT_FILENO, data, opt.data_len); else { /* print status here */ print_hex(data, opt.data_len); } } cleanup: free(data); close(fd); if (ifd > -1) close(ifd); if (errno) exit(1); } static void admin_passthru(const struct cmd *nf, int argc, char *argv[]) { passthru(nf, argc, argv); } static void io_passthru(const struct cmd *nf, int argc, char *argv[]) { passthru(nf, argc, argv); } static struct cmd admin_pass_cmd = { .name = "admin-passthru", .fn = admin_passthru, .ctx_size = sizeof(struct options), .opts = opts, .args = args, .descr = "Send a pass through Admin command to the specified device", }; static struct cmd io_pass_cmd = { .name = "io-passthru", .fn = io_passthru, .ctx_size = sizeof(struct options), .opts = opts, .args = args, - .descr = "Send a pass through Admin command to the specified device", + .descr = "Send a pass through I/O command to the specified device", }; CMD_COMMAND(admin_pass_cmd); CMD_COMMAND(io_pass_cmd); Index: stable/12 =================================================================== --- stable/12 (revision 366859) +++ stable/12 (revision 366860) Property changes on: stable/12 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r360546-360547