aboutsummaryrefslogtreecommitdiff
path: root/include/sg_pt_linux.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/sg_pt_linux.h')
-rw-r--r--include/sg_pt_linux.h202
1 files changed, 202 insertions, 0 deletions
diff --git a/include/sg_pt_linux.h b/include/sg_pt_linux.h
new file mode 100644
index 00000000..548a7634
--- /dev/null
+++ b/include/sg_pt_linux.h
@@ -0,0 +1,202 @@
+#ifndef SG_PT_LINUX_H
+#define SG_PT_LINUX_H
+
+/*
+ * Copyright (c) 2017-2018 Douglas Gilbert.
+ * All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the BSD_LICENSE file.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <linux/types.h>
+
+#include "sg_pt_nvme.h"
+
+/* This header is for internal use by the sg3_utils library (libsgutils)
+ * and is Linux specific. Best not to include it directly in code that
+ * is meant to be OS independent. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef HAVE_LINUX_BSG_H
+
+#define BSG_PROTOCOL_SCSI 0
+
+#define BSG_SUB_PROTOCOL_SCSI_CMD 0
+#define BSG_SUB_PROTOCOL_SCSI_TMF 1
+#define BSG_SUB_PROTOCOL_SCSI_TRANSPORT 2
+
+/*
+ * For flag constants below:
+ * sg.h sg_io_hdr also has bits defined for it's flags member. These
+ * two flag values (0x10 and 0x20) have the same meaning in sg.h . For
+ * bsg the BSG_FLAG_Q_AT_HEAD flag is ignored since it is the default.
+ */
+#define BSG_FLAG_Q_AT_TAIL 0x10 /* default is Q_AT_HEAD */
+#define BSG_FLAG_Q_AT_HEAD 0x20
+
+#ifndef SGV4_FLAG_YIELD_TAG
+#define SGV4_FLAG_YIELD_TAG 0x8
+#endif
+#ifndef SGV4_FLAG_FIND_BY_TAG
+#define SGV4_FLAG_FIND_BY_TAG 0x100
+#endif
+#ifndef SGV4_FLAG_IMMED
+#define SGV4_FLAG_IMMED 0x400
+#endif
+#ifndef SGV4_FLAG_IMMED
+#define SGV4_FLAG_IMMED 0x400
+#endif
+#ifndef SGV4_FLAG_DEV_SCOPE
+#define SGV4_FLAG_DEV_SCOPE 0x1000
+#endif
+#ifndef SGV4_FLAG_SHARE
+#define SGV4_FLAG_SHARE 0x2000
+#endif
+
+struct sg_io_v4 {
+ __s32 guard; /* [i] 'Q' to differentiate from v3 */
+ __u32 protocol; /* [i] 0 -> SCSI , .... */
+ __u32 subprotocol; /* [i] 0 -> SCSI command, 1 -> SCSI task
+ management function, .... */
+
+ __u32 request_len; /* [i] in bytes */
+ __u64 request; /* [i], [*i] {SCSI: cdb} */
+ __u64 request_tag; /* [i] {in sg 4.0+ this is out parameter} */
+ __u32 request_attr; /* [i] {SCSI: task attribute} */
+ __u32 request_priority; /* [i] {SCSI: task priority} */
+ __u32 request_extra; /* [i] {used for pack_id} */
+ __u32 max_response_len; /* [i] in bytes */
+ __u64 response; /* [i], [*o] {SCSI: (auto)sense data} */
+
+ /* "dout_": data out (to device); "din_": data in (from device) */
+ __u32 dout_iovec_count; /* [i] 0 -> "flat" dout transfer else
+ dout_xfer points to array of iovec */
+ __u32 dout_xfer_len; /* [i] bytes to be transferred to device */
+ __u32 din_iovec_count; /* [i] 0 -> "flat" din transfer */
+ __u32 din_xfer_len; /* [i] bytes to be transferred from device */
+ __u64 dout_xferp; /* [i], [*i] */
+ __u64 din_xferp; /* [i], [*o] */
+
+ __u32 timeout; /* [i] units: millisecond */
+ __u32 flags; /* [i] bit mask */
+ __u64 usr_ptr; /* [i->o] unused internally */
+ __u32 spare_in; /* [i] */
+
+ __u32 driver_status; /* [o] 0 -> ok */
+ __u32 transport_status; /* [o] 0 -> ok */
+ __u32 device_status; /* [o] {SCSI: command completion status} */
+ __u32 retry_delay; /* [o] {SCSI: status auxiliary information} */
+ __u32 info; /* [o] additional information */
+ __u32 duration; /* [o] time to complete, in milliseconds */
+ __u32 response_len; /* [o] bytes of response actually written */
+ __s32 din_resid; /* [o] din_xfer_len - actual_din_xfer_len */
+ __s32 dout_resid; /* [o] dout_xfer_len - actual_dout_xfer_len */
+ __u64 generated_tag; /* [o] {SCSI: transport generated task tag} */
+ __u32 spare_out; /* [o] */
+
+ __u32 padding;
+};
+
+#else
+
+#include <linux/bsg.h>
+
+#endif
+
+
+struct sg_pt_linux_scsi {
+ struct sg_io_v4 io_hdr; /* use v4 header as it is more general */
+ /* Leave io_hdr in first place of this structure */
+ bool is_sg;
+ bool is_bsg;
+ bool is_nvme; /* OS device type, if false ignore nvme_our_sntl */
+ bool nvme_our_sntl; /* true: our SNTL; false: received NVMe command */
+ bool nvme_stat_dnr; /* Do No Retry, part of completion status field */
+ bool nvme_stat_more; /* More, part of completion status field */
+ bool mdxfer_out; /* direction of metadata xfer, true->data-out */
+ int dev_fd; /* -1 if not given (yet) */
+ int in_err;
+ int os_err;
+ int sg_version; /* for deciding whether to use v3 or v4 interface */
+ uint32_t nvme_nsid; /* 1 to 0xfffffffe are possibly valid, 0
+ * implies dev_fd is not a NVMe device
+ * (is_nvme=false) or it is a NVMe char
+ * device (e.g. /dev/nvme0 ) */
+ uint32_t nvme_result; /* DW0 from completion queue */
+ uint32_t nvme_status; /* SCT|SC: DW3 27:17 from completion queue,
+ * note: the DNR+More bit are not there.
+ * The whole 16 byte completion q entry is
+ * sent back as sense data */
+ uint32_t mdxfer_len;
+ struct sg_sntl_dev_state_t dev_stat;
+ void * mdxferp;
+ uint8_t * nvme_id_ctlp; /* cached response to controller IDENTIFY */
+ uint8_t * free_nvme_id_ctlp;
+ uint8_t tmf_request[4];
+};
+
+struct sg_pt_base {
+ struct sg_pt_linux_scsi impl;
+};
+
+
+#ifndef sg_nvme_admin_cmd
+#define sg_nvme_admin_cmd sg_nvme_passthru_cmd
+#endif
+
+/* Linux NVMe related ioctls */
+#ifndef NVME_IOCTL_ID
+#define NVME_IOCTL_ID _IO('N', 0x40)
+#endif
+#ifndef NVME_IOCTL_ADMIN_CMD
+#define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct sg_nvme_admin_cmd)
+#endif
+#ifndef NVME_IOCTL_SUBMIT_IO
+#define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct sg_nvme_user_io)
+#endif
+#ifndef NVME_IOCTL_IO_CMD
+#define NVME_IOCTL_IO_CMD _IOWR('N', 0x43, struct sg_nvme_passthru_cmd)
+#endif
+#ifndef NVME_IOCTL_RESET
+#define NVME_IOCTL_RESET _IO('N', 0x44)
+#endif
+#ifndef NVME_IOCTL_SUBSYS_RESET
+#define NVME_IOCTL_SUBSYS_RESET _IO('N', 0x45)
+#endif
+#ifndef NVME_IOCTL_RESCAN
+#define NVME_IOCTL_RESCAN _IO('N', 0x46)
+#endif
+#if 0
+#define NVME_IOCTL_ADMIN64_CMD _IOWR('N', 0x47, struct nvme_passthru_cmd64)
+#define NVME_IOCTL_IO64_CMD _IOWR('N', 0x48, struct nvme_passthru_cmd64)
+#endif
+
+extern bool sg_bsg_nvme_char_major_checked;
+extern int sg_bsg_major;
+extern volatile int sg_nvme_char_major;
+extern long sg_lin_page_size;
+
+void sg_find_bsg_nvme_char_major(int verbose);
+int sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int time_secs, int vb);
+int sg_linux_get_sg_version(const struct sg_pt_base * vp);
+
+/* This trims given NVMe block device name in Linux (e.g. /dev/nvme0n1p5)
+ * to the name of its associated char device (e.g. /dev/nvme0). If this
+ * occurs true is returned and the char device name is placed in 'b' (as
+ * long as b_len is sufficient). Otherwise false is returned. */
+bool sg_get_nvme_char_devname(const char * nvme_block_devname, uint32_t b_len,
+ char * b);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of SG_PT_LINUX_H */