xref: /aosp_15_r20/external/sg3_utils/lib/sg_pt_solaris.c (revision 44704f698541f6367e81f991ef8bb54ccbf3fc18)
1*44704f69SBart Van Assche /*
2*44704f69SBart Van Assche  * Copyright (c) 2007-2021 Douglas Gilbert.
3*44704f69SBart Van Assche  * All rights reserved.
4*44704f69SBart Van Assche  * Use of this source code is governed by a BSD-style
5*44704f69SBart Van Assche  * license that can be found in the BSD_LICENSE file.
6*44704f69SBart Van Assche  *
7*44704f69SBart Van Assche  * SPDX-License-Identifier: BSD-2-Clause
8*44704f69SBart Van Assche  */
9*44704f69SBart Van Assche 
10*44704f69SBart Van Assche /* sg_pt_solaris version 1.15 20210617 */
11*44704f69SBart Van Assche 
12*44704f69SBart Van Assche #include <stdio.h>
13*44704f69SBart Van Assche #include <stdlib.h>
14*44704f69SBart Van Assche #include <stdarg.h>
15*44704f69SBart Van Assche #include <stdbool.h>
16*44704f69SBart Van Assche #include <string.h>
17*44704f69SBart Van Assche #include <ctype.h>
18*44704f69SBart Van Assche #include <unistd.h>
19*44704f69SBart Van Assche #include <errno.h>
20*44704f69SBart Van Assche #include <fcntl.h>
21*44704f69SBart Van Assche #include <sys/param.h>
22*44704f69SBart Van Assche 
23*44704f69SBart Van Assche /* Solaris headers */
24*44704f69SBart Van Assche #include <sys/scsi/generic/commands.h>
25*44704f69SBart Van Assche #include <sys/scsi/generic/status.h>
26*44704f69SBart Van Assche #include <sys/scsi/impl/types.h>
27*44704f69SBart Van Assche #include <sys/scsi/impl/uscsi.h>
28*44704f69SBart Van Assche 
29*44704f69SBart Van Assche #ifdef HAVE_CONFIG_H
30*44704f69SBart Van Assche #include "config.h"
31*44704f69SBart Van Assche #endif
32*44704f69SBart Van Assche 
33*44704f69SBart Van Assche #include "sg_pt.h"
34*44704f69SBart Van Assche #include "sg_lib.h"
35*44704f69SBart Van Assche 
36*44704f69SBart Van Assche 
37*44704f69SBart Van Assche #define DEF_TIMEOUT 60       /* 60 seconds */
38*44704f69SBart Van Assche 
39*44704f69SBart Van Assche struct sg_pt_solaris_scsi {
40*44704f69SBart Van Assche     struct uscsi_cmd uscsi;
41*44704f69SBart Van Assche     int max_sense_len;
42*44704f69SBart Van Assche     int in_err;
43*44704f69SBart Van Assche     int os_err;
44*44704f69SBart Van Assche     bool is_nvme;
45*44704f69SBart Van Assche     int dev_fd;
46*44704f69SBart Van Assche };
47*44704f69SBart Van Assche 
48*44704f69SBart Van Assche struct sg_pt_base {
49*44704f69SBart Van Assche     struct sg_pt_solaris_scsi impl;
50*44704f69SBart Van Assche };
51*44704f69SBart Van Assche 
52*44704f69SBart Van Assche 
53*44704f69SBart Van Assche /* Returns >= 0 if successful. If error in Unix returns negated errno. */
54*44704f69SBart Van Assche int
scsi_pt_open_device(const char * device_name,bool read_only,int verbose)55*44704f69SBart Van Assche scsi_pt_open_device(const char * device_name, bool read_only, int verbose)
56*44704f69SBart Van Assche {
57*44704f69SBart Van Assche     int oflags = 0 /* O_NONBLOCK*/ ;
58*44704f69SBart Van Assche 
59*44704f69SBart Van Assche     oflags |= (read_only ? O_RDONLY : O_RDWR);
60*44704f69SBart Van Assche     return scsi_pt_open_flags(device_name, oflags, verbose);
61*44704f69SBart Van Assche }
62*44704f69SBart Van Assche 
63*44704f69SBart Van Assche /* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed
64*44704f69SBart Van Assche  * together. The 'flags' argument is ignored in Solaris.
65*44704f69SBart Van Assche  * Returns >= 0 if successful, otherwise returns negated errno. */
66*44704f69SBart Van Assche int
scsi_pt_open_flags(const char * device_name,int flags_arg,int verbose)67*44704f69SBart Van Assche scsi_pt_open_flags(const char * device_name, int flags_arg, int verbose)
68*44704f69SBart Van Assche {
69*44704f69SBart Van Assche     int oflags = O_NONBLOCK | O_RDWR;
70*44704f69SBart Van Assche     int fd;
71*44704f69SBart Van Assche 
72*44704f69SBart Van Assche     flags_arg = flags_arg;  /* ignore flags argument, suppress warning */
73*44704f69SBart Van Assche     if (verbose > 1) {
74*44704f69SBart Van Assche         fprintf(sg_warnings_strm ? sg_warnings_strm : stderr,
75*44704f69SBart Van Assche                 "open %s with flags=0x%x\n", device_name, oflags);
76*44704f69SBart Van Assche     }
77*44704f69SBart Van Assche     fd = open(device_name, oflags);
78*44704f69SBart Van Assche     if (fd < 0)
79*44704f69SBart Van Assche         fd = -errno;
80*44704f69SBart Van Assche     return fd;
81*44704f69SBart Van Assche }
82*44704f69SBart Van Assche 
83*44704f69SBart Van Assche /* Returns 0 if successful. If error in Unix returns negated errno. */
84*44704f69SBart Van Assche int
scsi_pt_close_device(int device_fd)85*44704f69SBart Van Assche scsi_pt_close_device(int device_fd)
86*44704f69SBart Van Assche {
87*44704f69SBart Van Assche     int res;
88*44704f69SBart Van Assche 
89*44704f69SBart Van Assche     res = close(device_fd);
90*44704f69SBart Van Assche     if (res < 0)
91*44704f69SBart Van Assche         res = -errno;
92*44704f69SBart Van Assche     return res;
93*44704f69SBart Van Assche }
94*44704f69SBart Van Assche 
95*44704f69SBart Van Assche struct sg_pt_base *
construct_scsi_pt_obj_with_fd(int dev_fd,int verbose)96*44704f69SBart Van Assche construct_scsi_pt_obj_with_fd(int dev_fd, int verbose)
97*44704f69SBart Van Assche {
98*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp;
99*44704f69SBart Van Assche 
100*44704f69SBart Van Assche     ptp = (struct sg_pt_solaris_scsi *)
101*44704f69SBart Van Assche           calloc(1, sizeof(struct sg_pt_solaris_scsi));
102*44704f69SBart Van Assche     if (ptp) {
103*44704f69SBart Van Assche         ptp->dev_fd = (dev_fd < 0) ? -1 : dev_fd;
104*44704f69SBart Van Assche         ptp->is_nvme = false;
105*44704f69SBart Van Assche         ptp->uscsi.uscsi_timeout = DEF_TIMEOUT;
106*44704f69SBart Van Assche         /* Comment in Illumos suggest USCSI_ISOLATE and USCSI_DIAGNOSE (both)
107*44704f69SBart Van Assche          * seem to mean "don't retry" which is what we want. */
108*44704f69SBart Van Assche         ptp->uscsi.uscsi_flags = USCSI_ISOLATE | USCSI_DIAGNOSE |
109*44704f69SBart Van Assche                                  USCSI_RQENABLE;
110*44704f69SBart Van Assche     } else if (verbose)
111*44704f69SBart Van Assche         fprintf(sg_warnings_strm ? sg_warnings_strm : stderr,
112*44704f69SBart Van Assche                 "%s: calloc() out of memory\n", __func__);
113*44704f69SBart Van Assche     return (struct sg_pt_base *)ptp;
114*44704f69SBart Van Assche }
115*44704f69SBart Van Assche 
116*44704f69SBart Van Assche struct sg_pt_base *
construct_scsi_pt_obj()117*44704f69SBart Van Assche construct_scsi_pt_obj()
118*44704f69SBart Van Assche {
119*44704f69SBart Van Assche     return construct_scsi_pt_obj_with_fd(-1, 0);
120*44704f69SBart Van Assche }
121*44704f69SBart Van Assche 
122*44704f69SBart Van Assche void
destruct_scsi_pt_obj(struct sg_pt_base * vp)123*44704f69SBart Van Assche destruct_scsi_pt_obj(struct sg_pt_base * vp)
124*44704f69SBart Van Assche {
125*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
126*44704f69SBart Van Assche 
127*44704f69SBart Van Assche     if (ptp)
128*44704f69SBart Van Assche         free(ptp);
129*44704f69SBart Van Assche }
130*44704f69SBart Van Assche 
131*44704f69SBart Van Assche void
clear_scsi_pt_obj(struct sg_pt_base * vp)132*44704f69SBart Van Assche clear_scsi_pt_obj(struct sg_pt_base * vp)
133*44704f69SBart Van Assche {
134*44704f69SBart Van Assche     bool is_nvme;
135*44704f69SBart Van Assche     int dev_fd;
136*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
137*44704f69SBart Van Assche 
138*44704f69SBart Van Assche     if (ptp) {
139*44704f69SBart Van Assche         is_nvme = ptp->is_nvme;
140*44704f69SBart Van Assche         dev_fd = ptp->dev_fd;
141*44704f69SBart Van Assche         memset(ptp, 0, sizeof(struct sg_pt_solaris_scsi));
142*44704f69SBart Van Assche         ptp->dev_fd = dev_fd;
143*44704f69SBart Van Assche         ptp->is_nvme = is_nvme;
144*44704f69SBart Van Assche         ptp->uscsi.uscsi_timeout = DEF_TIMEOUT;
145*44704f69SBart Van Assche         ptp->uscsi.uscsi_flags = USCSI_ISOLATE | USCSI_DIAGNOSE |
146*44704f69SBart Van Assche                                  USCSI_RQENABLE;
147*44704f69SBart Van Assche     }
148*44704f69SBart Van Assche }
149*44704f69SBart Van Assche 
150*44704f69SBart Van Assche void
partial_clear_scsi_pt_obj(struct sg_pt_base * vp)151*44704f69SBart Van Assche partial_clear_scsi_pt_obj(struct sg_pt_base * vp)
152*44704f69SBart Van Assche {
153*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
154*44704f69SBart Van Assche 
155*44704f69SBart Van Assche     if (ptp) {
156*44704f69SBart Van Assche         ptp->in_err = 0;
157*44704f69SBart Van Assche         ptp->os_err = 0;
158*44704f69SBart Van Assche         ptp->uscsi.uscsi_status = 0;
159*44704f69SBart Van Assche         ptp->uscsi.uscsi_bufaddr = NULL;
160*44704f69SBart Van Assche         ptp->uscsi.uscsi_buflen = 0;
161*44704f69SBart Van Assche         ptp->uscsi.uscsi_flags = USCSI_ISOLATE | USCSI_DIAGNOSE |
162*44704f69SBart Van Assche                                  USCSI_RQENABLE;
163*44704f69SBart Van Assche     }
164*44704f69SBart Van Assche }
165*44704f69SBart Van Assche 
166*44704f69SBart Van Assche void
set_scsi_pt_cdb(struct sg_pt_base * vp,const uint8_t * cdb,int cdb_len)167*44704f69SBart Van Assche set_scsi_pt_cdb(struct sg_pt_base * vp, const uint8_t * cdb,
168*44704f69SBart Van Assche                 int cdb_len)
169*44704f69SBart Van Assche {
170*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
171*44704f69SBart Van Assche 
172*44704f69SBart Van Assche     ptp->uscsi.uscsi_cdb = (char *)cdb;
173*44704f69SBart Van Assche     ptp->uscsi.uscsi_cdblen = cdb_len;
174*44704f69SBart Van Assche }
175*44704f69SBart Van Assche 
176*44704f69SBart Van Assche int
get_scsi_pt_cdb_len(const struct sg_pt_base * vp)177*44704f69SBart Van Assche get_scsi_pt_cdb_len(const struct sg_pt_base * vp)
178*44704f69SBart Van Assche {
179*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
180*44704f69SBart Van Assche 
181*44704f69SBart Van Assche     return ptp->uscsi.uscsi_cdblen;
182*44704f69SBart Van Assche }
183*44704f69SBart Van Assche 
184*44704f69SBart Van Assche uint8_t *
get_scsi_pt_cdb_buf(const struct sg_pt_base * vp)185*44704f69SBart Van Assche get_scsi_pt_cdb_buf(const struct sg_pt_base * vp)
186*44704f69SBart Van Assche {
187*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
188*44704f69SBart Van Assche 
189*44704f69SBart Van Assche     return (uint8_t *)ptp->uscsi.uscsi_cdb;
190*44704f69SBart Van Assche }
191*44704f69SBart Van Assche 
192*44704f69SBart Van Assche void
set_scsi_pt_sense(struct sg_pt_base * vp,uint8_t * sense,int max_sense_len)193*44704f69SBart Van Assche set_scsi_pt_sense(struct sg_pt_base * vp, uint8_t * sense,
194*44704f69SBart Van Assche                   int max_sense_len)
195*44704f69SBart Van Assche {
196*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
197*44704f69SBart Van Assche 
198*44704f69SBart Van Assche     if (sense && (max_sense_len > 0))
199*44704f69SBart Van Assche         memset(sense, 0, max_sense_len);
200*44704f69SBart Van Assche     ptp->uscsi.uscsi_rqbuf = (char *)sense;
201*44704f69SBart Van Assche     ptp->uscsi.uscsi_rqlen = max_sense_len;
202*44704f69SBart Van Assche     ptp->max_sense_len = max_sense_len;
203*44704f69SBart Van Assche }
204*44704f69SBart Van Assche 
205*44704f69SBart Van Assche /* from device */
206*44704f69SBart Van Assche void
set_scsi_pt_data_in(struct sg_pt_base * vp,uint8_t * dxferp,int dxfer_len)207*44704f69SBart Van Assche set_scsi_pt_data_in(struct sg_pt_base * vp, uint8_t * dxferp,
208*44704f69SBart Van Assche                     int dxfer_len)
209*44704f69SBart Van Assche {
210*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
211*44704f69SBart Van Assche 
212*44704f69SBart Van Assche     if (ptp->uscsi.uscsi_bufaddr)
213*44704f69SBart Van Assche         ++ptp->in_err;
214*44704f69SBart Van Assche     if (dxfer_len > 0) {
215*44704f69SBart Van Assche         ptp->uscsi.uscsi_bufaddr = (char *)dxferp;
216*44704f69SBart Van Assche         ptp->uscsi.uscsi_buflen = dxfer_len;
217*44704f69SBart Van Assche         ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_DIAGNOSE |
218*44704f69SBart Van Assche                                  USCSI_RQENABLE;
219*44704f69SBart Van Assche     }
220*44704f69SBart Van Assche }
221*44704f69SBart Van Assche 
222*44704f69SBart Van Assche /* to device */
223*44704f69SBart Van Assche void
set_scsi_pt_data_out(struct sg_pt_base * vp,const uint8_t * dxferp,int dxfer_len)224*44704f69SBart Van Assche set_scsi_pt_data_out(struct sg_pt_base * vp, const uint8_t * dxferp,
225*44704f69SBart Van Assche                      int dxfer_len)
226*44704f69SBart Van Assche {
227*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
228*44704f69SBart Van Assche 
229*44704f69SBart Van Assche     if (ptp->uscsi.uscsi_bufaddr)
230*44704f69SBart Van Assche         ++ptp->in_err;
231*44704f69SBart Van Assche     if (dxfer_len > 0) {
232*44704f69SBart Van Assche         ptp->uscsi.uscsi_bufaddr = (char *)dxferp;
233*44704f69SBart Van Assche         ptp->uscsi.uscsi_buflen = dxfer_len;
234*44704f69SBart Van Assche         ptp->uscsi.uscsi_flags = USCSI_WRITE | USCSI_ISOLATE | USCSI_DIAGNOSE |
235*44704f69SBart Van Assche                                  USCSI_RQENABLE;
236*44704f69SBart Van Assche     }
237*44704f69SBart Van Assche }
238*44704f69SBart Van Assche 
239*44704f69SBart Van Assche void
set_scsi_pt_packet_id(struct sg_pt_base * vp,int pack_id)240*44704f69SBart Van Assche set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id)
241*44704f69SBart Van Assche {
242*44704f69SBart Van Assche     // struct sg_pt_solaris_scsi * ptp = &vp->impl;
243*44704f69SBart Van Assche 
244*44704f69SBart Van Assche     vp = vp;                    /* ignore and suppress warning */
245*44704f69SBart Van Assche     pack_id = pack_id;          /* ignore and suppress warning */
246*44704f69SBart Van Assche }
247*44704f69SBart Van Assche 
248*44704f69SBart Van Assche void
set_scsi_pt_tag(struct sg_pt_base * vp,uint64_t tag)249*44704f69SBart Van Assche set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag)
250*44704f69SBart Van Assche {
251*44704f69SBart Van Assche     // struct sg_pt_solaris_scsi * ptp = &vp->impl;
252*44704f69SBart Van Assche 
253*44704f69SBart Van Assche     vp = vp;                    /* ignore and suppress warning */
254*44704f69SBart Van Assche     tag = tag;                  /* ignore and suppress warning */
255*44704f69SBart Van Assche }
256*44704f69SBart Van Assche 
257*44704f69SBart Van Assche /* Note that task management function codes are transport specific */
258*44704f69SBart Van Assche void
set_scsi_pt_task_management(struct sg_pt_base * vp,int tmf_code)259*44704f69SBart Van Assche set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code)
260*44704f69SBart Van Assche {
261*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
262*44704f69SBart Van Assche 
263*44704f69SBart Van Assche     ++ptp->in_err;
264*44704f69SBart Van Assche     tmf_code = tmf_code;        /* dummy to silence compiler */
265*44704f69SBart Van Assche }
266*44704f69SBart Van Assche 
267*44704f69SBart Van Assche void
set_scsi_pt_task_attr(struct sg_pt_base * vp,int attribute,int priority)268*44704f69SBart Van Assche set_scsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority)
269*44704f69SBart Van Assche {
270*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
271*44704f69SBart Van Assche 
272*44704f69SBart Van Assche     ++ptp->in_err;
273*44704f69SBart Van Assche     attribute = attribute;      /* dummy to silence compiler */
274*44704f69SBart Van Assche     priority = priority;        /* dummy to silence compiler */
275*44704f69SBart Van Assche }
276*44704f69SBart Van Assche 
277*44704f69SBart Van Assche void
set_scsi_pt_flags(struct sg_pt_base * objp,int flags)278*44704f69SBart Van Assche set_scsi_pt_flags(struct sg_pt_base * objp, int flags)
279*44704f69SBart Van Assche {
280*44704f69SBart Van Assche     /* do nothing, suppress warnings */
281*44704f69SBart Van Assche     objp = objp;
282*44704f69SBart Van Assche     flags = flags;
283*44704f69SBart Van Assche }
284*44704f69SBart Van Assche 
285*44704f69SBart Van Assche /* Executes SCSI command (or at least forwards it to lower layers).
286*44704f69SBart Van Assche  * Clears os_err field prior to active call (whose result may set it
287*44704f69SBart Van Assche  * again). */
288*44704f69SBart Van Assche int
do_scsi_pt(struct sg_pt_base * vp,int fd,int time_secs,int verbose)289*44704f69SBart Van Assche do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose)
290*44704f69SBart Van Assche {
291*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
292*44704f69SBart Van Assche     FILE * ferr = sg_warnings_strm ? sg_warnings_strm : stderr;
293*44704f69SBart Van Assche 
294*44704f69SBart Van Assche     ptp->os_err = 0;
295*44704f69SBart Van Assche     if (ptp->in_err) {
296*44704f69SBart Van Assche         if (verbose)
297*44704f69SBart Van Assche             fprintf(ferr, "Replicated or unused set_scsi_pt... functions\n");
298*44704f69SBart Van Assche         return SCSI_PT_DO_BAD_PARAMS;
299*44704f69SBart Van Assche     }
300*44704f69SBart Van Assche     if (fd < 0) {
301*44704f69SBart Van Assche         if (ptp->dev_fd < 0) {
302*44704f69SBart Van Assche             if (verbose)
303*44704f69SBart Van Assche                 fprintf(ferr, "%s: No device file descriptor given\n",
304*44704f69SBart Van Assche                         __func__);
305*44704f69SBart Van Assche             return SCSI_PT_DO_BAD_PARAMS;
306*44704f69SBart Van Assche         }
307*44704f69SBart Van Assche     } else {
308*44704f69SBart Van Assche         if (ptp->dev_fd >= 0) {
309*44704f69SBart Van Assche             if (fd != ptp->dev_fd) {
310*44704f69SBart Van Assche                 if (verbose)
311*44704f69SBart Van Assche                     fprintf(ferr, "%s: file descriptor given to create and "
312*44704f69SBart Van Assche                             "this differ\n", __func__);
313*44704f69SBart Van Assche                 return SCSI_PT_DO_BAD_PARAMS;
314*44704f69SBart Van Assche             }
315*44704f69SBart Van Assche         } else
316*44704f69SBart Van Assche             ptp->dev_fd = fd;
317*44704f69SBart Van Assche     }
318*44704f69SBart Van Assche     if (NULL == ptp->uscsi.uscsi_cdb) {
319*44704f69SBart Van Assche         if (verbose)
320*44704f69SBart Van Assche             fprintf(ferr, "%s: No SCSI command (cdb) given\n", __func__);
321*44704f69SBart Van Assche         return SCSI_PT_DO_BAD_PARAMS;
322*44704f69SBart Van Assche     }
323*44704f69SBart Van Assche     if (time_secs > 0)
324*44704f69SBart Van Assche         ptp->uscsi.uscsi_timeout = time_secs;
325*44704f69SBart Van Assche 
326*44704f69SBart Van Assche     if (ioctl(ptp->dev_fd, USCSICMD, &ptp->uscsi)) {
327*44704f69SBart Van Assche         ptp->os_err = errno;
328*44704f69SBart Van Assche         if ((EIO == ptp->os_err) && ptp->uscsi.uscsi_status) {
329*44704f69SBart Van Assche             ptp->os_err = 0;
330*44704f69SBart Van Assche             return 0;
331*44704f69SBart Van Assche         }
332*44704f69SBart Van Assche         if (verbose)
333*44704f69SBart Van Assche             fprintf(ferr, "%s: ioctl(USCSICMD) failed with os_err (errno) "
334*44704f69SBart Van Assche                     "= %d\n", __func__, ptp->os_err);
335*44704f69SBart Van Assche         return -ptp->os_err;
336*44704f69SBart Van Assche     }
337*44704f69SBart Van Assche     return 0;
338*44704f69SBart Van Assche }
339*44704f69SBart Van Assche 
340*44704f69SBart Van Assche int
get_scsi_pt_result_category(const struct sg_pt_base * vp)341*44704f69SBart Van Assche get_scsi_pt_result_category(const struct sg_pt_base * vp)
342*44704f69SBart Van Assche {
343*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
344*44704f69SBart Van Assche     int scsi_st = ptp->uscsi.uscsi_status;
345*44704f69SBart Van Assche 
346*44704f69SBart Van Assche     if (ptp->os_err)
347*44704f69SBart Van Assche         return SCSI_PT_RESULT_OS_ERR;
348*44704f69SBart Van Assche     else if ((SAM_STAT_CHECK_CONDITION == scsi_st) ||
349*44704f69SBart Van Assche              (SAM_STAT_COMMAND_TERMINATED == scsi_st))
350*44704f69SBart Van Assche         return SCSI_PT_RESULT_SENSE;
351*44704f69SBart Van Assche     else if (scsi_st)
352*44704f69SBart Van Assche         return SCSI_PT_RESULT_STATUS;
353*44704f69SBart Van Assche     else
354*44704f69SBart Van Assche         return SCSI_PT_RESULT_GOOD;
355*44704f69SBart Van Assche }
356*44704f69SBart Van Assche 
357*44704f69SBart Van Assche uint32_t
get_pt_result(const struct sg_pt_base * vp)358*44704f69SBart Van Assche get_pt_result(const struct sg_pt_base * vp)
359*44704f69SBart Van Assche {
360*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
361*44704f69SBart Van Assche 
362*44704f69SBart Van Assche     return (uint32_t)ptp->uscsi.uscsi_status;
363*44704f69SBart Van Assche }
364*44704f69SBart Van Assche 
365*44704f69SBart Van Assche int
get_scsi_pt_resid(const struct sg_pt_base * vp)366*44704f69SBart Van Assche get_scsi_pt_resid(const struct sg_pt_base * vp)
367*44704f69SBart Van Assche {
368*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
369*44704f69SBart Van Assche 
370*44704f69SBart Van Assche     return ptp->uscsi.uscsi_resid;
371*44704f69SBart Van Assche }
372*44704f69SBart Van Assche 
373*44704f69SBart Van Assche void
get_pt_req_lengths(const struct sg_pt_base * vp,int * req_dinp,int * req_doutp)374*44704f69SBart Van Assche get_pt_req_lengths(const struct sg_pt_base * vp, int * req_dinp,
375*44704f69SBart Van Assche                    int * req_doutp)
376*44704f69SBart Van Assche {
377*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
378*44704f69SBart Van Assche     int dxfer_len = ptp->uscsi.uscsi_buflen;
379*44704f69SBart Van Assche     int flags = ptp->uscsi.uscsi_flags;
380*44704f69SBart Van Assche 
381*44704f69SBart Van Assche     if (req_dinp) {
382*44704f69SBart Van Assche         if ((dxfer_len > 0) && (USCSI_READ & flags))
383*44704f69SBart Van Assche             *req_dinp = dxfer_len;
384*44704f69SBart Van Assche         else
385*44704f69SBart Van Assche             *req_dinp = 0;
386*44704f69SBart Van Assche     }
387*44704f69SBart Van Assche     if (req_doutp) {
388*44704f69SBart Van Assche         if ((dxfer_len > 0) && (USCSI_WRITE & flags))
389*44704f69SBart Van Assche             *req_doutp = dxfer_len;
390*44704f69SBart Van Assche         else
391*44704f69SBart Van Assche             *req_doutp = 0;
392*44704f69SBart Van Assche     }
393*44704f69SBart Van Assche }
394*44704f69SBart Van Assche 
395*44704f69SBart Van Assche void
get_pt_actual_lengths(const struct sg_pt_base * vp,int * act_dinp,int * act_doutp)396*44704f69SBart Van Assche get_pt_actual_lengths(const struct sg_pt_base * vp, int * act_dinp,
397*44704f69SBart Van Assche                       int * act_doutp)
398*44704f69SBart Van Assche {
399*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
400*44704f69SBart Van Assche     int dxfer_len = ptp->uscsi.uscsi_buflen;
401*44704f69SBart Van Assche     int flags = ptp->uscsi.uscsi_flags;
402*44704f69SBart Van Assche 
403*44704f69SBart Van Assche     if (act_dinp) {
404*44704f69SBart Van Assche         if ((dxfer_len > 0) && (USCSI_READ & flags))
405*44704f69SBart Van Assche             *act_dinp = dxfer_len - ptp->uscsi.uscsi_resid;
406*44704f69SBart Van Assche         else
407*44704f69SBart Van Assche             *act_dinp = 0;
408*44704f69SBart Van Assche     }
409*44704f69SBart Van Assche     if (act_doutp) {
410*44704f69SBart Van Assche         if ((dxfer_len > 0) && (USCSI_WRITE & flags))
411*44704f69SBart Van Assche             *act_doutp = dxfer_len - ptp->uscsi.uscsi_resid;
412*44704f69SBart Van Assche         else
413*44704f69SBart Van Assche             *act_doutp = 0;
414*44704f69SBart Van Assche     }
415*44704f69SBart Van Assche }
416*44704f69SBart Van Assche 
417*44704f69SBart Van Assche int
get_scsi_pt_status_response(const struct sg_pt_base * vp)418*44704f69SBart Van Assche get_scsi_pt_status_response(const struct sg_pt_base * vp)
419*44704f69SBart Van Assche {
420*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
421*44704f69SBart Van Assche 
422*44704f69SBart Van Assche     return ptp->uscsi.uscsi_status;
423*44704f69SBart Van Assche }
424*44704f69SBart Van Assche 
425*44704f69SBart Van Assche int
get_scsi_pt_sense_len(const struct sg_pt_base * vp)426*44704f69SBart Van Assche get_scsi_pt_sense_len(const struct sg_pt_base * vp)
427*44704f69SBart Van Assche {
428*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
429*44704f69SBart Van Assche     int res;
430*44704f69SBart Van Assche 
431*44704f69SBart Van Assche     if (ptp->max_sense_len > 0) {
432*44704f69SBart Van Assche         res = ptp->max_sense_len - ptp->uscsi.uscsi_rqresid;
433*44704f69SBart Van Assche         return (res > 0) ? res : 0;
434*44704f69SBart Van Assche     }
435*44704f69SBart Van Assche     return 0;
436*44704f69SBart Van Assche }
437*44704f69SBart Van Assche 
438*44704f69SBart Van Assche uint8_t *
get_scsi_pt_sense_buf(const struct sg_pt_base * vp)439*44704f69SBart Van Assche get_scsi_pt_sense_buf(const struct sg_pt_base * vp)
440*44704f69SBart Van Assche {
441*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
442*44704f69SBart Van Assche 
443*44704f69SBart Van Assche     return (uint8_t *)ptp->uscsi.uscsi_rqbuf;
444*44704f69SBart Van Assche }
445*44704f69SBart Van Assche 
446*44704f69SBart Van Assche int
get_scsi_pt_duration_ms(const struct sg_pt_base * vp)447*44704f69SBart Van Assche get_scsi_pt_duration_ms(const struct sg_pt_base * vp)
448*44704f69SBart Van Assche {
449*44704f69SBart Van Assche     // const struct sg_pt_solaris_scsi * ptp = &vp->impl;
450*44704f69SBart Van Assche 
451*44704f69SBart Van Assche     vp = vp;            /* ignore and suppress warning */
452*44704f69SBart Van Assche     return -1;          /* not available */
453*44704f69SBart Van Assche }
454*44704f69SBart Van Assche 
455*44704f69SBart Van Assche /* If not available return 0 otherwise return number of nanoseconds that the
456*44704f69SBart Van Assche  * lower layers (and hardware) took to execute the command just completed. */
457*44704f69SBart Van Assche uint64_t
get_pt_duration_ns(const struct sg_pt_base * vp)458*44704f69SBart Van Assche get_pt_duration_ns(const struct sg_pt_base * vp __attribute__ ((unused)))
459*44704f69SBart Van Assche {
460*44704f69SBart Van Assche     return 0;
461*44704f69SBart Van Assche }
462*44704f69SBart Van Assche 
463*44704f69SBart Van Assche int
get_scsi_pt_transport_err(const struct sg_pt_base * vp)464*44704f69SBart Van Assche get_scsi_pt_transport_err(const struct sg_pt_base * vp)
465*44704f69SBart Van Assche {
466*44704f69SBart Van Assche     // const struct sg_pt_solaris_scsi * ptp = &vp->impl;
467*44704f69SBart Van Assche 
468*44704f69SBart Van Assche     if (vp) { ; }            /* ignore and suppress warning */
469*44704f69SBart Van Assche     return 0;
470*44704f69SBart Van Assche }
471*44704f69SBart Van Assche 
472*44704f69SBart Van Assche void
set_scsi_pt_transport_err(struct sg_pt_base * vp,int err)473*44704f69SBart Van Assche set_scsi_pt_transport_err(struct sg_pt_base * vp, int err)
474*44704f69SBart Van Assche {
475*44704f69SBart Van Assche     // const struct sg_pt_solaris_scsi * ptp = &vp->impl;
476*44704f69SBart Van Assche 
477*44704f69SBart Van Assche     if (vp) { ; }            /* ignore and suppress warning */
478*44704f69SBart Van Assche     if (err) { ; }           /* ignore and suppress warning */
479*44704f69SBart Van Assche }
480*44704f69SBart Van Assche 
481*44704f69SBart Van Assche int
get_scsi_pt_os_err(const struct sg_pt_base * vp)482*44704f69SBart Van Assche get_scsi_pt_os_err(const struct sg_pt_base * vp)
483*44704f69SBart Van Assche {
484*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
485*44704f69SBart Van Assche 
486*44704f69SBart Van Assche     return ptp->os_err;
487*44704f69SBart Van Assche }
488*44704f69SBart Van Assche 
489*44704f69SBart Van Assche bool
pt_device_is_nvme(const struct sg_pt_base * vp)490*44704f69SBart Van Assche pt_device_is_nvme(const struct sg_pt_base * vp)
491*44704f69SBart Van Assche {
492*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
493*44704f69SBart Van Assche 
494*44704f69SBart Van Assche     return ptp ? ptp->is_nvme : false;
495*44704f69SBart Van Assche }
496*44704f69SBart Van Assche 
497*44704f69SBart Van Assche char *
get_scsi_pt_transport_err_str(const struct sg_pt_base * vp,int max_b_len,char * b)498*44704f69SBart Van Assche get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len,
499*44704f69SBart Van Assche                               char * b)
500*44704f69SBart Van Assche {
501*44704f69SBart Van Assche     // const struct sg_pt_solaris_scsi * ptp = &vp->impl;
502*44704f69SBart Van Assche 
503*44704f69SBart Van Assche     vp = vp;            /* ignore and suppress warning */
504*44704f69SBart Van Assche     if (max_b_len > 0)
505*44704f69SBart Van Assche         b[0] = '\0';
506*44704f69SBart Van Assche 
507*44704f69SBart Van Assche     return b;
508*44704f69SBart Van Assche }
509*44704f69SBart Van Assche 
510*44704f69SBart Van Assche char *
get_scsi_pt_os_err_str(const struct sg_pt_base * vp,int max_b_len,char * b)511*44704f69SBart Van Assche get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b)
512*44704f69SBart Van Assche {
513*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
514*44704f69SBart Van Assche     const char * cp;
515*44704f69SBart Van Assche 
516*44704f69SBart Van Assche     cp = safe_strerror(ptp->os_err);
517*44704f69SBart Van Assche     strncpy(b, cp, max_b_len);
518*44704f69SBart Van Assche     if ((int)strlen(cp) >= max_b_len)
519*44704f69SBart Van Assche         b[max_b_len - 1] = '\0';
520*44704f69SBart Van Assche     return b;
521*44704f69SBart Van Assche }
522*44704f69SBart Van Assche 
523*44704f69SBart Van Assche int
do_nvm_pt(struct sg_pt_base * vp,int submq,int timeout_secs,int verbose)524*44704f69SBart Van Assche do_nvm_pt(struct sg_pt_base * vp, int submq, int timeout_secs, int verbose)
525*44704f69SBart Van Assche {
526*44704f69SBart Van Assche     if (vp) { }
527*44704f69SBart Van Assche     if (submq) { }
528*44704f69SBart Van Assche     if (timeout_secs) { }
529*44704f69SBart Van Assche     if (verbose) { }
530*44704f69SBart Van Assche     return SCSI_PT_DO_NOT_SUPPORTED;
531*44704f69SBart Van Assche }
532*44704f69SBart Van Assche 
533*44704f69SBart Van Assche int
check_pt_file_handle(int device_fd,const char * device_name,int vb)534*44704f69SBart Van Assche check_pt_file_handle(int device_fd, const char * device_name, int vb)
535*44704f69SBart Van Assche {
536*44704f69SBart Van Assche     if (device_fd) {}
537*44704f69SBart Van Assche     if (device_name) {}
538*44704f69SBart Van Assche     if (vb) {}
539*44704f69SBart Van Assche     return 0;
540*44704f69SBart Van Assche }
541*44704f69SBart Van Assche 
542*44704f69SBart Van Assche /* Valid file handles (which is the return value) are >= 0 . Returns -1
543*44704f69SBart Van Assche  * if there is no valid file handle. */
544*44704f69SBart Van Assche int
get_pt_file_handle(const struct sg_pt_base * vp)545*44704f69SBart Van Assche get_pt_file_handle(const struct sg_pt_base * vp)
546*44704f69SBart Van Assche {
547*44704f69SBart Van Assche     const struct sg_pt_solaris_scsi * ptp = &vp->impl;
548*44704f69SBart Van Assche 
549*44704f69SBart Van Assche     return ptp->dev_fd;
550*44704f69SBart Van Assche }
551*44704f69SBart Van Assche 
552*44704f69SBart Van Assche 
553*44704f69SBart Van Assche /* If a NVMe block device (which includes the NSID) handle is associated
554*44704f69SBart Van Assche  * with 'vp', then its NSID is returned (values range from 0x1 to
555*44704f69SBart Van Assche  * 0xffffffe). Otherwise 0 is returned. */
556*44704f69SBart Van Assche uint32_t
get_pt_nvme_nsid(const struct sg_pt_base * vp)557*44704f69SBart Van Assche get_pt_nvme_nsid(const struct sg_pt_base * vp)
558*44704f69SBart Van Assche {
559*44704f69SBart Van Assche     if (vp) { }
560*44704f69SBart Van Assche     return 0;
561*44704f69SBart Van Assche }
562*44704f69SBart Van Assche 
563*44704f69SBart Van Assche /* Forget any previous dev_han and install the one given. May attempt to
564*44704f69SBart Van Assche  * find file type (e.g. if pass-though) from OS so there could be an error.
565*44704f69SBart Van Assche  * Returns 0 for success or the same value as get_scsi_pt_os_err()
566*44704f69SBart Van Assche  * will return. dev_han should be >= 0 for a valid file handle or -1 . */
567*44704f69SBart Van Assche int
set_pt_file_handle(struct sg_pt_base * vp,int dev_han,int vb)568*44704f69SBart Van Assche set_pt_file_handle(struct sg_pt_base * vp, int dev_han, int vb)
569*44704f69SBart Van Assche {
570*44704f69SBart Van Assche     struct sg_pt_solaris_scsi * ptp = &vp->impl;
571*44704f69SBart Van Assche 
572*44704f69SBart Van Assche     if (vb) {}
573*44704f69SBart Van Assche     ptp->dev_fd = (dev_han < 0) ? -1 : dev_han;
574*44704f69SBart Van Assche     ptp->in_err = 0;
575*44704f69SBart Van Assche     ptp->os_err = 0;
576*44704f69SBart Van Assche     ptp->is_nvme = false;
577*44704f69SBart Van Assche     return 0;
578*44704f69SBart Van Assche }
579