Am Sun, May 26, 2024 at 10:56:05AM -0400 schrieb Kenneth Westerback:
> The diff below enables smartmontools (smartctl & smartd) support for
> NVMe disks on -current kernels with the latest nvme(4) passthrough
> commits.
> 
> Obvious features tested and work for me on various amd64 boxes and my m1
> macmini.
> 
> ian@ has also succesfully tested it.
> 
> Thoughts? OK?
Works on my system as well. (Own only a single nvme driven box)

> --
> .... Ken
> 
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/sysutils/smartmontools/Makefile,v
> diff -u -p -u -p -r1.50 Makefile
> --- Makefile  27 Sep 2023 17:16:34 -0000      1.50
> +++ Makefile  26 May 2024 14:54:25 -0000
> @@ -2,6 +2,7 @@ COMMENT=              control and monitor storage sy
> 
>  # XXX at update time check whether C++11 is actually needed
>  DISTNAME=            smartmontools-7.4
> +REVISION=            0
>  CATEGORIES=          sysutils
> 
>  HOMEPAGE=            https://www.smartmontools.org/
> Index: patches/patch-openbsd_nvme_ioctl_h
> ===================================================================
> RCS file: patches/patch-openbsd_nvme_ioctl_h
> diff -N patches/patch-openbsd_nvme_ioctl_h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-openbsd_nvme_ioctl_h        26 May 2024 14:54:25 -0000
> @@ -0,0 +1,78 @@
> +Index: openbsd_nvme_ioctl.h
> +--- openbsd_nvme_ioctl.h.orig
> ++++ openbsd_nvme_ioctl.h
> +@@ -0,0 +1,74 @@
> ++/*
> ++ * Copyright (c) 2024 Kenneth R Westerback <k...@openbsd.org>
> ++ *
> ++ * Permission to use, copy, modify, and distribute this software for any
> ++ * purpose with or without fee is hereby granted, provided that the above
> ++ * copyright notice and this permission notice appear in all copies.
> ++ *
> ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> ++ */
> ++
> ++#define     NVME_PASSTHROUGH_CMD            _IOWR('n', 0, struct 
> nvme_pt_cmd)
> ++
> ++struct nvme_pt_status {
> ++    int                     ps_dv_unit;
> ++    int                     ps_nsid;
> ++    int                     ps_flags;
> ++#define NVME_CQE_SCT(_f)    ((_f) & (0x07 << 9))
> ++#define  NVME_CQE_SCT_GENERIC               (0x00 << 9)
> ++#define NVME_CQE_SC(_f)             ((_f) & (0xff << 1))
> ++#define  NVME_CQE_SC_SUCCESS                (0x00 << 1)
> ++    uint32_t                ps_csts;
> ++    uint32_t                ps_cc;
> ++};
> ++
> ++#define     BIO_MSG_COUNT   5
> ++#define     BIO_MSG_LEN     128
> ++
> ++struct bio_msg {
> ++    int             bm_type;
> ++    char            bm_msg[BIO_MSG_LEN];
> ++};
> ++
> ++struct bio_status {
> ++    char            bs_controller[16];
> ++    int             bs_status;
> ++    int             bs_msg_count;
> ++    struct bio_msg  bs_msgs[BIO_MSG_COUNT];
> ++};
> ++
> ++struct bio {
> ++    void                    *bio_cookie;
> ++    struct bio_status       bio_status;
> ++};
> ++
> ++struct nvme_pt_cmd {
> ++    /* Commands may arrive via /dev/bio. */
> ++    struct bio              pt_bio;
> ++
> ++    /* The sqe fields that the caller may specify. */
> ++    uint8_t                 pt_opcode;
> ++    uint32_t                pt_nsid;
> ++    uint32_t                pt_cdw10;
> ++    uint32_t                pt_cdw11;
> ++    uint32_t                pt_cdw12;
> ++    uint32_t                pt_cdw13;
> ++    uint32_t                pt_cdw14;
> ++    uint32_t                pt_cdw15;
> ++
> ++    caddr_t                 pt_status;
> ++    uint32_t                pt_statuslen;
> ++
> ++    caddr_t                 pt_databuf;     /* User space address. */
> ++    uint32_t                pt_databuflen;  /* Length of buffer. */
> ++};
> ++
> ++#define     nvme_completion_is_error(_flags)                                
> \
> ++    ((NVME_CQE_SC(_flags) != NVME_CQE_SC_SUCCESS)                   \
> ++        || (NVME_CQE_SCT(_flags) != NVME_CQE_SCT_GENERIC))
> Index: patches/patch-os_openbsd_cpp
> ===================================================================
> RCS file: patches/patch-os_openbsd_cpp
> diff -N patches/patch-os_openbsd_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-os_openbsd_cpp      26 May 2024 14:54:25 -0000
> @@ -0,0 +1,196 @@
> +Index: os_openbsd.cpp
> +--- os_openbsd.cpp.orig
> ++++ os_openbsd.cpp
> +@@ -14,6 +14,7 @@
> +
> + #include "atacmds.h"
> + #include "scsicmds.h"
> ++#include "nvmecmds.h"
> + #include "utility.h"
> + #include "os_openbsd.h"
> +
> +@@ -22,11 +23,29 @@
> + #include <sys/stat.h>
> + #include <util.h>
> +
> ++// based on OpenBSD "/usr/include/dev/ic/nvmeio.h" && 
> "/usr/include/dev/biovar.h"
> ++#include "openbsd_nvme_ioctl.h"     // NVME_PASSTHROUGH_CMD, 
> nvme_completion_is_error
> + const char * os_openbsd_cpp_cvsid = "$Id: os_openbsd.cpp 5393 2022-05-29 
> 05:08:10Z dpgilbert $"
> +   OS_OPENBSD_H_CVSID;
> +
> + #define ARGUSED(x) ((void)(x))
> +
> ++bool sd_is_nvme(const char *dev)
> ++{
> ++      struct nvme_pt_cmd pt;
> ++      memset(&pt, 0, sizeof(pt));
> ++      pt.pt_opcode = smartmontools::nvme_admin_identify;
> ++
> ++      int fd = ::open(dev, O_RDWR);
> ++      if (fd == -1)
> ++        return false;
> ++
> ++      int status = ioctl(fd, NVME_PASSTHROUGH_CMD, &pt);
> ++      close(fd);
> ++
> ++      return status != -1 || errno != ENOTTY;
> ++}
> ++
> + 
> /////////////////////////////////////////////////////////////////////////////
> +
> + namespace os_openbsd { // No need to publish anything, name provided for 
> Doxygen
> +@@ -209,6 +228,80 @@ bool openbsd_ata_device::ata_pass_through(const ata_cm
> + }
> +
> + 
> /////////////////////////////////////////////////////////////////////////////
> ++/// NVMe support
> ++
> ++class openbsd_nvme_device
> ++: public /*implements*/ nvme_device,
> ++  public /*extends*/ openbsd_smart_device
> ++{
> ++public:
> ++  openbsd_nvme_device(smart_interface * intf, const char * dev_name,
> ++    const char * req_type, unsigned nsid);
> ++
> ++  virtual bool open() override;
> ++
> ++  virtual bool nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & 
> out) override;
> ++};
> ++
> ++openbsd_nvme_device::openbsd_nvme_device(smart_interface * intf, const char 
> * dev_name,
> ++  const char * req_type, unsigned nsid)
> ++: smart_device(intf, dev_name, "nvme", req_type),
> ++  nvme_device(nsid),
> ++  openbsd_smart_device()
> ++{
> ++}
> ++
> ++bool openbsd_nvme_device::open()
> ++{
> ++  const char *dev = get_dev_name();
> ++  int fd;
> ++
> ++  if ((fd = ::open(dev, O_RDWR)) == -1) {
> ++    set_err(errno, "can't open sd device");
> ++    return false;
> ++  }
> ++
> ++  set_fd(fd);
> ++
> ++  return true;
> ++}
> ++
> ++bool openbsd_nvme_device::nvme_pass_through(const nvme_cmd_in & in, 
> nvme_cmd_out & out)
> ++{
> ++  struct nvme_pt_cmd pt;
> ++  struct nvme_pt_status ps;
> ++
> ++  memset(&ps, 0, sizeof(ps));
> ++  memset(&pt.pt_bio, 0, sizeof(pt.pt_bio));
> ++
> ++  pt.pt_opcode = in.opcode;
> ++  pt.pt_nsid = in.nsid;
> ++  pt.pt_databuf = (caddr_t)in.buffer;
> ++  pt.pt_databuflen = in.size;
> ++  pt.pt_cdw10 = in.cdw10;
> ++  pt.pt_cdw11 = in.cdw11;
> ++  pt.pt_cdw12 = in.cdw12;
> ++  pt.pt_cdw13 = in.cdw13;
> ++  pt.pt_cdw14 = in.cdw14;
> ++  pt.pt_cdw15 = in.cdw15;
> ++  pt.pt_status = (char *)&ps;
> ++  pt.pt_statuslen = sizeof(ps);
> ++
> ++  int status = ioctl(get_fd(), NVME_PASSTHROUGH_CMD, &pt);
> ++
> ++  if (status == -1)
> ++    return set_err(errno, "NVME_PASSTHROUGH_CMD: %s", strerror(errno));
> ++
> ++  out.result = 0; // cqe.cdw0 (Command specific result) is not provided
> ++
> ++  if (nvme_completion_is_error(ps.ps_flags))
> ++    return set_nvme_err(out, nvme_completion_is_error(ps.ps_flags));
> ++
> ++  return true;
> ++}
> ++
> ++
> ++/////////////////////////////////////////////////////////////////////////////
> + /// Standard SCSI support
> +
> + class openbsd_scsi_device
> +@@ -381,6 +474,9 @@ class openbsd_smart_interface (protected)
> +
> +   virtual scsi_device * get_scsi_device(const char * name, const char * 
> type) override;
> +
> ++  virtual nvme_device * get_nvme_device(const char * name, const char * 
> type,
> ++    unsigned nsid) override;
> ++
> +   virtual smart_device * autodetect_smart_device(const char * name) 
> override;
> +
> +   virtual smart_device * get_custom_smart_device(const char * name, const 
> char * type) override;
> +@@ -434,6 +530,11 @@ scsi_device * openbsd_smart_interface::get_scsi_device
> +   return new openbsd_scsi_device(this, name, type);
> + }
> +
> ++nvme_device * openbsd_smart_interface::get_nvme_device(const char * name, 
> const char * type, unsigned nsid)
> ++{
> ++  return new openbsd_nvme_device(this, name, type, nsid);
> ++}
> ++
> + int openbsd_smart_interface::get_dev_names(char ***names, const char 
> *prefix)
> + {
> +   char *disknames, *p, **mp;
> +@@ -504,6 +605,7 @@ bool openbsd_smart_interface::scan_smart_devices(smart
> +
> +     bool scan_ata = !*type || !strcmp(type, "ata");
> +     bool scan_scsi = !*type || !strcmp(type, "scsi") || !strcmp(type, 
> "sat");
> ++    bool scan_nvme = !*type || !strcmp(type, "nvme");
> +
> +     // Make namelists
> +     char * * atanames = 0; int numata = 0;
> +@@ -517,7 +619,7 @@ bool openbsd_smart_interface::scan_smart_devices(smart
> +
> +     char * * scsinames = 0; int numscsi = 0;
> +     char * * scsitapenames = 0; int numscsitape = 0;
> +-    if (scan_scsi) {
> ++    if (scan_scsi || scan_nvme) {
> +       numscsi = get_dev_names(&scsinames, net_dev_scsi_disk);
> +       if (numscsi < 0) {
> +         set_err(ENOMEM);
> +@@ -541,9 +643,17 @@ bool openbsd_smart_interface::scan_smart_devices(smart
> +     if(numata) free(atanames);
> +
> +     for (i = 0; i < numscsi; i++) {
> +-      scsi_device * scsidev = new openbsd_scsi_device(this, scsinames[i], 
> type, true /*scanning*/);
> +-      if (scsidev)
> +-        devlist.push_back(scsidev);
> ++      if (sd_is_nvme(scsinames[i])) {
> ++        if (scan_nvme) {
> ++          nvme_device * nvmedev = new openbsd_nvme_device(this, 
> scsinames[i], type, true /*scanning*/);
> ++          if (nvmedev)
> ++            devlist.push_back(nvmedev);
> ++        }
> ++      } else if (scan_scsi) {
> ++        scsi_device * scsidev = new openbsd_scsi_device(this, scsinames[i], 
> type, true /*scanning*/);
> ++        if (scsidev)
> ++          devlist.push_back(scsidev);
> ++      }
> +       free(scsinames[i]);
> +     }
> +     if(numscsi) free(scsinames);
> +@@ -588,8 +698,11 @@ smart_device * openbsd_smart_interface::autodetect_sma
> +       // XXX get USB vendor ID, product ID and version from sd(4)/umass(4).
> +       // XXX check sat device via get_usb_dev_type_by_id().
> +
> +-      // No USB bridge found, assume regular SCSI or SAT device
> +-      return get_scsi_device(name, "");
> ++      // No USB bridge found, decide if it's NVME or regular SCSI or SAT 
> device
> ++      if (sd_is_nvme(name))
> ++        return get_nvme_device(name, "nvme", 0);
> ++      else
> ++        return get_scsi_device(name, "");
> +     }
> +     if (!strncmp(net_dev_scsi_tape, test_name, strlen(net_dev_scsi_tape)))
> +       return get_scsi_device(name, "scsi");
> Index: patches/patch-smartctl_8_in
> ===================================================================
> RCS file: patches/patch-smartctl_8_in
> diff -N patches/patch-smartctl_8_in
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-smartctl_8_in       26 May 2024 14:54:25 -0000
> @@ -0,0 +1,170 @@
> +Index: smartctl.8.in
> +--- smartctl.8.in.orig
> ++++ smartctl.8.in
> +@@ -233,11 +233,11 @@ in the smartmontools database (see \*(Aq\-v\*(Aq optio
> + drive model family may also be printed.
> + If \*(Aq\-n\*(Aq (see below) is specified, the power mode of the drive is
> + printed.
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + [NVMe] For NVMe devices the information is obtained from the Identify
> + Controller and the Identify Namespace data structure.
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .TP
> + .B \-\-identify[=[w][nvb]]
> + [ATA only] Prints an annotated table of the IDENTIFY DEVICE data.
> +@@ -266,12 +266,12 @@ the SMART options which require support for 48-bit ATA
> + For SCSI, this is equivalent to
> + .br
> + \*(Aq\-H \-i \-A \-l error \-l selftest\*(Aq.
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + For NVMe, this is equivalent to
> + .br
> + \*(Aq\-H \-i \-c \-A \-l error \-l selftest\*(Aq.
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .TP
> + .B \-x, \-\-xall
> + Prints all SMART and non-SMART information about the device.
> +@@ -290,12 +290,12 @@ For SCSI disks, this is equivalent to
> + \-l defects \-l envrep \-l genstats \-l ssd \-l zdevstat\*(Aq
> + .br
> + and for SCSI tape drives and changers, add \*(Aq\-l tapedevstat\*(Aq.
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + For NVMe, this is equivalent to
> + .br
> + \*(Aq\-H \-i \-c \-A \-l error \-l selftest\*(Aq.
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .TP
> + .B \-\-scan
> + Scans for devices and prints each device name, device type and protocol
> +@@ -1184,11 +1184,11 @@ Prefailure SMART Attribute value is less than or 
> equal
> + [SCSI tape drive or changer] The TapeAlert status is obtained by reading the
> + TapeAlert log page, but only if this option is given twice (see
> + \fBTAPE DRIVES\fP for the rationale).
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + [NVMe] NVMe status is obtained by reading the "Critical Warning" byte from
> + the SMART/Health Information log.
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .TP
> + .B \-c, \-\-capabilities
> + [ATA] Prints only the generic SMART capabilities.  These
> +@@ -1197,11 +1197,11 @@ respond to some of the different SMART commands.  For
> + shows if the device logs errors, if it supports offline surface
> + scanning, and so on.  If the device can carry out self-tests, this
> + option also shows the estimated time required to run those tests.
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + [NVMe] Prints various NVMe device capabilities obtained from the Identify
> + Controller and the Identify Namespace data structure.
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .TP
> + .B \-A, \-\-attributes
> + [ATA] Prints only the vendor specific SMART Attributes.  The Attributes
> +@@ -1298,11 +1298,11 @@ and start-stop cycle counter log pages.
> + Certain vendor specific attributes are listed if recognised.
> + The attributes are output in a relatively free format (compared with ATA
> + disk attributes).
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + [NVMe] For NVMe devices the attributes are obtained from the SMART/Health
> + Information log.
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .TP
> + .B \-f FORMAT, \-\-format=FORMAT
> + [ATA only] Selects the output format of the attributes:
> +@@ -1407,7 +1407,7 @@ receives a command which is not implemented or is not
> + \- [SCSI] prints the error counter log pages for reads, write and verifies.
> + The verify row is only output if it has an element other than zero.
> + .Sp
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .I error[,NUM]
> + \- [NVMe] prints the NVMe Error Information log.
> + Only the 16 most recent log entries are printed by default.
> +@@ -1419,7 +1419,7 @@ Note that the contents of this log is not preserved ac
> + controller resets, but the value of \*(AqError Information Log Entries\*(Aq
> + from SMART/Health Information log is.
> + .Sp
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .I xerror[,NUM][,error]
> + \- [ATA only] prints the Extended Comprehensive SMART error log
> + (General Purpose Log address 0x03).  Unlike the Summary SMART error
> +@@ -1472,12 +1472,12 @@ If provided, the SCSI Sense Key (SK), Additional 
> Sense
> + Additional Sense Code Qualifier (ASCQ) are also printed.  The self tests
> + can be run using the \*(Aq\-t\*(Aq option described below (using the ATA
> + test terminology).
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + .I selftest
> + \- [NVMe: NEW EXPERIMENTAL SMARTCTL 7.4 FEATURE]
> + prints the NVMe self-test log.
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + .I xselftest[,NUM][,selftest]
> + \- [ATA only] prints the Extended SMART self-test log (General Purpose
> +@@ -1663,7 +1663,7 @@ This command:
> + writes a binary representation of the one sector log 0x11
> + (SATA Phy Event Counters) to file log.bin.
> + .Sp
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .I nvmelog,PAGE,SIZE
> + \- [NVMe only] prints a hex dump of the first SIZE bytes from the NVMe
> + log with identifier PAGE.
> +@@ -1672,7 +1672,7 @@ SIZE is a hexadecimal number in the range from 0x4 to
> + \fBWARNING: Do not specify the identifier of an unknown log page.
> + Reading a log page may have undesirable side effects.\fP
> + .Sp
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .I ssd
> + \- [ATA] prints the Solid State Device Statistics log page.
> + This has the same effect as \*(Aq\-l devstat,7\*(Aq, see above.
> +@@ -2130,12 +2130,12 @@ with other disks use the \*(Aq\-c\*(Aq option to 
> monit
> + .Sp
> + .I short
> + \- [SCSI] runs the "Background short" self-test.
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + .I short
> + \- [NVMe: NEW EXPERIMENTAL SMARTCTL 7.4 FEATURE]
> + runs the "Short" self-test for current namespace.
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + .I long
> + \- [ATA] runs SMART Extended Self Test (tens of minutes to several hours).
> +@@ -2146,12 +2146,12 @@ below).
> + .Sp
> + .I long
> + \- [SCSI] runs the "Background long" self-test.
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + .I long
> + \- [NVMe: NEW EXPERIMENTAL SMARTCTL 7.4 FEATURE]
> + runs the "Extended" self-test for current namespace.
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .Sp
> + .I conveyance
> + \- [ATA only] runs a SMART Conveyance Self Test (minutes).  This
> Index: patches/patch-smartd_8_in
> ===================================================================
> RCS file: patches/patch-smartd_8_in
> diff -N patches/patch-smartd_8_in
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-smartd_8_in 26 May 2024 14:54:25 -0000
> @@ -0,0 +1,17 @@
> +Index: smartd.8.in
> +--- smartd.8.in.orig
> ++++ smartd.8.in
> +@@ -458,11 +458,11 @@ this option are:
> + .I scsiioctl
> + \- report only ioctl() transactions with SCSI devices.
> + .Sp
> +-.\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %IF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + .I nvmeioctl
> + \- report only ioctl() transactions with NVMe devices.
> + .Sp
> +-.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
> ++.\" %ENDIF OS Darwin FreeBSD Linux NetBSD OpenBSD Windows Cygwin
> + Any argument may include a positive integer to specify the level of
> + detail that should be reported.  The argument should be followed by a
> + comma then the integer with no spaces.  For example, \fIataioctl,2\fP

Reply via email to