xref: /aosp_15_r20/external/sg3_utils/include/sg_pt_linux.h (revision 44704f698541f6367e81f991ef8bb54ccbf3fc18)
1*44704f69SBart Van Assche #ifndef SG_PT_LINUX_H
2*44704f69SBart Van Assche #define SG_PT_LINUX_H
3*44704f69SBart Van Assche 
4*44704f69SBart Van Assche /*
5*44704f69SBart Van Assche  * Copyright (c) 2017-2018 Douglas Gilbert.
6*44704f69SBart Van Assche  * All rights reserved.
7*44704f69SBart Van Assche  * Use of this source code is governed by a BSD-style
8*44704f69SBart Van Assche  * license that can be found in the BSD_LICENSE file.
9*44704f69SBart Van Assche  *
10*44704f69SBart Van Assche  * SPDX-License-Identifier: BSD-2-Clause
11*44704f69SBart Van Assche  */
12*44704f69SBart Van Assche 
13*44704f69SBart Van Assche #include <stdint.h>
14*44704f69SBart Van Assche #include <stdbool.h>
15*44704f69SBart Van Assche 
16*44704f69SBart Van Assche #include <linux/types.h>
17*44704f69SBart Van Assche 
18*44704f69SBart Van Assche #include "sg_pt_nvme.h"
19*44704f69SBart Van Assche 
20*44704f69SBart Van Assche /* This header is for internal use by the sg3_utils library (libsgutils)
21*44704f69SBart Van Assche  * and is Linux specific. Best not to include it directly in code that
22*44704f69SBart Van Assche  * is meant to be OS independent. */
23*44704f69SBart Van Assche 
24*44704f69SBart Van Assche #ifdef __cplusplus
25*44704f69SBart Van Assche extern "C" {
26*44704f69SBart Van Assche #endif
27*44704f69SBart Van Assche 
28*44704f69SBart Van Assche #ifndef HAVE_LINUX_BSG_H
29*44704f69SBart Van Assche 
30*44704f69SBart Van Assche #define BSG_PROTOCOL_SCSI               0
31*44704f69SBart Van Assche 
32*44704f69SBart Van Assche #define BSG_SUB_PROTOCOL_SCSI_CMD       0
33*44704f69SBart Van Assche #define BSG_SUB_PROTOCOL_SCSI_TMF       1
34*44704f69SBart Van Assche #define BSG_SUB_PROTOCOL_SCSI_TRANSPORT 2
35*44704f69SBart Van Assche 
36*44704f69SBart Van Assche /*
37*44704f69SBart Van Assche  * For flag constants below:
38*44704f69SBart Van Assche  * sg.h sg_io_hdr also has bits defined for it's flags member. These
39*44704f69SBart Van Assche  * two flag values (0x10 and 0x20) have the same meaning in sg.h . For
40*44704f69SBart Van Assche  * bsg the BSG_FLAG_Q_AT_HEAD flag is ignored since it is the default.
41*44704f69SBart Van Assche  */
42*44704f69SBart Van Assche #define BSG_FLAG_Q_AT_TAIL 0x10 /* default is Q_AT_HEAD */
43*44704f69SBart Van Assche #define BSG_FLAG_Q_AT_HEAD 0x20
44*44704f69SBart Van Assche 
45*44704f69SBart Van Assche #ifndef SGV4_FLAG_YIELD_TAG
46*44704f69SBart Van Assche #define SGV4_FLAG_YIELD_TAG 0x8
47*44704f69SBart Van Assche #endif
48*44704f69SBart Van Assche #ifndef SGV4_FLAG_FIND_BY_TAG
49*44704f69SBart Van Assche #define SGV4_FLAG_FIND_BY_TAG 0x100
50*44704f69SBart Van Assche #endif
51*44704f69SBart Van Assche #ifndef SGV4_FLAG_IMMED
52*44704f69SBart Van Assche #define SGV4_FLAG_IMMED 0x400
53*44704f69SBart Van Assche #endif
54*44704f69SBart Van Assche #ifndef SGV4_FLAG_IMMED
55*44704f69SBart Van Assche #define SGV4_FLAG_IMMED 0x400
56*44704f69SBart Van Assche #endif
57*44704f69SBart Van Assche #ifndef SGV4_FLAG_DEV_SCOPE
58*44704f69SBart Van Assche #define SGV4_FLAG_DEV_SCOPE 0x1000
59*44704f69SBart Van Assche #endif
60*44704f69SBart Van Assche #ifndef SGV4_FLAG_SHARE
61*44704f69SBart Van Assche #define SGV4_FLAG_SHARE 0x2000
62*44704f69SBart Van Assche #endif
63*44704f69SBart Van Assche 
64*44704f69SBart Van Assche struct sg_io_v4 {
65*44704f69SBart Van Assche         __s32 guard;            /* [i] 'Q' to differentiate from v3 */
66*44704f69SBart Van Assche         __u32 protocol;         /* [i] 0 -> SCSI , .... */
67*44704f69SBart Van Assche         __u32 subprotocol;      /* [i] 0 -> SCSI command, 1 -> SCSI task
68*44704f69SBart Van Assche                                    management function, .... */
69*44704f69SBart Van Assche 
70*44704f69SBart Van Assche         __u32 request_len;      /* [i] in bytes */
71*44704f69SBart Van Assche         __u64 request;          /* [i], [*i] {SCSI: cdb} */
72*44704f69SBart Van Assche         __u64 request_tag;      /* [i] {in sg 4.0+ this is out parameter} */
73*44704f69SBart Van Assche         __u32 request_attr;     /* [i] {SCSI: task attribute} */
74*44704f69SBart Van Assche         __u32 request_priority; /* [i] {SCSI: task priority} */
75*44704f69SBart Van Assche         __u32 request_extra;    /* [i] {used for pack_id} */
76*44704f69SBart Van Assche         __u32 max_response_len; /* [i] in bytes */
77*44704f69SBart Van Assche         __u64 response;         /* [i], [*o] {SCSI: (auto)sense data} */
78*44704f69SBart Van Assche 
79*44704f69SBart Van Assche         /* "dout_": data out (to device); "din_": data in (from device) */
80*44704f69SBart Van Assche         __u32 dout_iovec_count; /* [i] 0 -> "flat" dout transfer else
81*44704f69SBart Van Assche                                    dout_xfer points to array of iovec */
82*44704f69SBart Van Assche         __u32 dout_xfer_len;    /* [i] bytes to be transferred to device */
83*44704f69SBart Van Assche         __u32 din_iovec_count;  /* [i] 0 -> "flat" din transfer */
84*44704f69SBart Van Assche         __u32 din_xfer_len;     /* [i] bytes to be transferred from device */
85*44704f69SBart Van Assche         __u64 dout_xferp;       /* [i], [*i] */
86*44704f69SBart Van Assche         __u64 din_xferp;        /* [i], [*o] */
87*44704f69SBart Van Assche 
88*44704f69SBart Van Assche         __u32 timeout;          /* [i] units: millisecond */
89*44704f69SBart Van Assche         __u32 flags;            /* [i] bit mask */
90*44704f69SBart Van Assche         __u64 usr_ptr;          /* [i->o] unused internally */
91*44704f69SBart Van Assche         __u32 spare_in;         /* [i] */
92*44704f69SBart Van Assche 
93*44704f69SBart Van Assche         __u32 driver_status;    /* [o] 0 -> ok */
94*44704f69SBart Van Assche         __u32 transport_status; /* [o] 0 -> ok */
95*44704f69SBart Van Assche         __u32 device_status;    /* [o] {SCSI: command completion status} */
96*44704f69SBart Van Assche         __u32 retry_delay;      /* [o] {SCSI: status auxiliary information} */
97*44704f69SBart Van Assche         __u32 info;             /* [o] additional information */
98*44704f69SBart Van Assche         __u32 duration;         /* [o] time to complete, in milliseconds */
99*44704f69SBart Van Assche         __u32 response_len;     /* [o] bytes of response actually written */
100*44704f69SBart Van Assche         __s32 din_resid;        /* [o] din_xfer_len - actual_din_xfer_len */
101*44704f69SBart Van Assche         __s32 dout_resid;       /* [o] dout_xfer_len - actual_dout_xfer_len */
102*44704f69SBart Van Assche         __u64 generated_tag;    /* [o] {SCSI: transport generated task tag} */
103*44704f69SBart Van Assche         __u32 spare_out;        /* [o] */
104*44704f69SBart Van Assche 
105*44704f69SBart Van Assche         __u32 padding;
106*44704f69SBart Van Assche };
107*44704f69SBart Van Assche 
108*44704f69SBart Van Assche #else
109*44704f69SBart Van Assche 
110*44704f69SBart Van Assche #include <linux/bsg.h>
111*44704f69SBart Van Assche 
112*44704f69SBart Van Assche #endif
113*44704f69SBart Van Assche 
114*44704f69SBart Van Assche 
115*44704f69SBart Van Assche struct sg_pt_linux_scsi {
116*44704f69SBart Van Assche     struct sg_io_v4 io_hdr;     /* use v4 header as it is more general */
117*44704f69SBart Van Assche     /* Leave io_hdr in first place of this structure */
118*44704f69SBart Van Assche     bool is_sg;
119*44704f69SBart Van Assche     bool is_bsg;
120*44704f69SBart Van Assche     bool is_nvme;       /* OS device type, if false ignore nvme_our_sntl */
121*44704f69SBart Van Assche     bool nvme_our_sntl; /* true: our SNTL; false: received NVMe command */
122*44704f69SBart Van Assche     bool nvme_stat_dnr; /* Do No Retry, part of completion status field */
123*44704f69SBart Van Assche     bool nvme_stat_more; /* More, part of completion status field */
124*44704f69SBart Van Assche     bool mdxfer_out;    /* direction of metadata xfer, true->data-out */
125*44704f69SBart Van Assche     int dev_fd;                 /* -1 if not given (yet) */
126*44704f69SBart Van Assche     int in_err;
127*44704f69SBart Van Assche     int os_err;
128*44704f69SBart Van Assche     int sg_version;     /* for deciding whether to use v3 or v4 interface */
129*44704f69SBart Van Assche     uint32_t nvme_nsid;         /* 1 to 0xfffffffe are possibly valid, 0
130*44704f69SBart Van Assche                                  * implies dev_fd is not a NVMe device
131*44704f69SBart Van Assche                                  * (is_nvme=false) or it is a NVMe char
132*44704f69SBart Van Assche                                  * device (e.g. /dev/nvme0 ) */
133*44704f69SBart Van Assche     uint32_t nvme_result;       /* DW0 from completion queue */
134*44704f69SBart Van Assche     uint32_t nvme_status;       /* SCT|SC: DW3 27:17 from completion queue,
135*44704f69SBart Van Assche                                  * note: the DNR+More bit are not there.
136*44704f69SBart Van Assche                                  * The whole 16 byte completion q entry is
137*44704f69SBart Van Assche                                  * sent back as sense data */
138*44704f69SBart Van Assche     uint32_t mdxfer_len;
139*44704f69SBart Van Assche     struct sg_sntl_dev_state_t dev_stat;
140*44704f69SBart Van Assche     void * mdxferp;
141*44704f69SBart Van Assche     uint8_t * nvme_id_ctlp;     /* cached response to controller IDENTIFY */
142*44704f69SBart Van Assche     uint8_t * free_nvme_id_ctlp;
143*44704f69SBart Van Assche     uint8_t tmf_request[4];
144*44704f69SBart Van Assche };
145*44704f69SBart Van Assche 
146*44704f69SBart Van Assche struct sg_pt_base {
147*44704f69SBart Van Assche     struct sg_pt_linux_scsi impl;
148*44704f69SBart Van Assche };
149*44704f69SBart Van Assche 
150*44704f69SBart Van Assche 
151*44704f69SBart Van Assche #ifndef sg_nvme_admin_cmd
152*44704f69SBart Van Assche #define sg_nvme_admin_cmd sg_nvme_passthru_cmd
153*44704f69SBart Van Assche #endif
154*44704f69SBart Van Assche 
155*44704f69SBart Van Assche /* Linux NVMe related ioctls */
156*44704f69SBart Van Assche #ifndef NVME_IOCTL_ID
157*44704f69SBart Van Assche #define NVME_IOCTL_ID           _IO('N', 0x40)
158*44704f69SBart Van Assche #endif
159*44704f69SBart Van Assche #ifndef NVME_IOCTL_ADMIN_CMD
160*44704f69SBart Van Assche #define NVME_IOCTL_ADMIN_CMD    _IOWR('N', 0x41, struct sg_nvme_admin_cmd)
161*44704f69SBart Van Assche #endif
162*44704f69SBart Van Assche #ifndef NVME_IOCTL_SUBMIT_IO
163*44704f69SBart Van Assche #define NVME_IOCTL_SUBMIT_IO    _IOW('N', 0x42, struct sg_nvme_user_io)
164*44704f69SBart Van Assche #endif
165*44704f69SBart Van Assche #ifndef NVME_IOCTL_IO_CMD
166*44704f69SBart Van Assche #define NVME_IOCTL_IO_CMD       _IOWR('N', 0x43, struct sg_nvme_passthru_cmd)
167*44704f69SBart Van Assche #endif
168*44704f69SBart Van Assche #ifndef NVME_IOCTL_RESET
169*44704f69SBart Van Assche #define NVME_IOCTL_RESET        _IO('N', 0x44)
170*44704f69SBart Van Assche #endif
171*44704f69SBart Van Assche #ifndef NVME_IOCTL_SUBSYS_RESET
172*44704f69SBart Van Assche #define NVME_IOCTL_SUBSYS_RESET _IO('N', 0x45)
173*44704f69SBart Van Assche #endif
174*44704f69SBart Van Assche #ifndef NVME_IOCTL_RESCAN
175*44704f69SBart Van Assche #define NVME_IOCTL_RESCAN       _IO('N', 0x46)
176*44704f69SBart Van Assche #endif
177*44704f69SBart Van Assche #if 0
178*44704f69SBart Van Assche #define NVME_IOCTL_ADMIN64_CMD  _IOWR('N', 0x47, struct nvme_passthru_cmd64)
179*44704f69SBart Van Assche #define NVME_IOCTL_IO64_CMD     _IOWR('N', 0x48, struct nvme_passthru_cmd64)
180*44704f69SBart Van Assche #endif
181*44704f69SBart Van Assche 
182*44704f69SBart Van Assche extern bool sg_bsg_nvme_char_major_checked;
183*44704f69SBart Van Assche extern int sg_bsg_major;
184*44704f69SBart Van Assche extern volatile int sg_nvme_char_major;
185*44704f69SBart Van Assche extern long sg_lin_page_size;
186*44704f69SBart Van Assche 
187*44704f69SBart Van Assche void sg_find_bsg_nvme_char_major(int verbose);
188*44704f69SBart Van Assche int sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int time_secs, int vb);
189*44704f69SBart Van Assche int sg_linux_get_sg_version(const struct sg_pt_base * vp);
190*44704f69SBart Van Assche 
191*44704f69SBart Van Assche /* This trims given NVMe block device name in Linux (e.g. /dev/nvme0n1p5)
192*44704f69SBart Van Assche  * to the name of its associated char device (e.g. /dev/nvme0). If this
193*44704f69SBart Van Assche  * occurs true is returned and the char device name is placed in 'b' (as
194*44704f69SBart Van Assche  * long as b_len is sufficient). Otherwise false is returned. */
195*44704f69SBart Van Assche bool sg_get_nvme_char_devname(const char * nvme_block_devname, uint32_t b_len,
196*44704f69SBart Van Assche                               char * b);
197*44704f69SBart Van Assche 
198*44704f69SBart Van Assche #ifdef __cplusplus
199*44704f69SBart Van Assche }
200*44704f69SBart Van Assche #endif
201*44704f69SBart Van Assche 
202*44704f69SBart Van Assche #endif          /* end of SG_PT_LINUX_H */
203