]> granicus.if.org Git - strace/blob - sg_io_v3.c
sg_io: decode struct sg_io_hdr.flags and struct sg_io_v4.flags
[strace] / sg_io_v3.c
1 /*
2  * Copyright (c) 2007 Vladimir Nadvornik <nadvornik@suse.cz>
3  * Copyright (c) 2007-2017 Dmitry V. Levin <ldv@altlinux.org>
4  * Copyright (c) 2015 Bart Van Assche <bart.vanassche@sandisk.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "defs.h"
31
32 #ifdef HAVE_SCSI_SG_H
33
34 #include DEF_MPERS_TYPE(struct_sg_io_hdr)
35
36 # include <scsi/sg.h>
37
38 typedef struct sg_io_hdr struct_sg_io_hdr;
39
40 #endif /* HAVE_SCSI_SG_H */
41
42 #include MPERS_DEFS
43
44 #ifdef HAVE_SCSI_SG_H
45 # include "xlat/sg_io_dxfer_direction.h"
46 # include "xlat/sg_io_flags.h"
47
48 static void
49 print_sg_io_buffer(struct tcb *const tcp, const kernel_ulong_t addr,
50                    const unsigned int len)
51 {
52         printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX);
53 }
54
55 static int
56 decode_request(struct tcb *const tcp, const kernel_ulong_t arg)
57 {
58         struct_sg_io_hdr sg_io;
59         static const size_t skip_iid =
60                 offsetof(struct_sg_io_hdr, dxfer_direction);
61
62         tprints("{interface_id='S', ");
63         if (umoven_or_printaddr(tcp, arg + skip_iid, sizeof(sg_io) - skip_iid,
64                                 &sg_io.dxfer_direction)) {
65                 tprints("}");
66                 return RVAL_DECODED | 1;
67         }
68
69         tprints("dxfer_direction=");
70         printxval(sg_io_dxfer_direction, sg_io.dxfer_direction,
71                   "SG_DXFER_???");
72         tprintf(", cmd[%u]=", sg_io.cmd_len);
73         print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.cmdp), sg_io.cmd_len);
74         tprintf(", mx_sb_len=%d", sg_io.mx_sb_len);
75         tprintf(", iovec_count=%d", sg_io.iovec_count);
76         tprintf(", dxfer_len=%u", sg_io.dxfer_len);
77         tprintf(", timeout=%u", sg_io.timeout);
78         tprints(", flags=");
79         printflags(sg_io_flags, sg_io.flags, "SG_FLAG_???");
80
81         if (sg_io.dxfer_direction == SG_DXFER_TO_DEV ||
82             sg_io.dxfer_direction == SG_DXFER_TO_FROM_DEV) {
83                 tprintf(", data[%u]=", sg_io.dxfer_len);
84                 if (sg_io.iovec_count)
85                         tprint_iov_upto(tcp, sg_io.iovec_count,
86                                         ptr_to_kulong(sg_io.dxferp),
87                                         IOV_DECODE_STR,
88                                         sg_io.dxfer_len);
89                 else
90                         print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.dxferp),
91                                            sg_io.dxfer_len);
92         }
93         return 1;
94 }
95
96 static int
97 decode_response(struct tcb *const tcp, const kernel_ulong_t arg)
98 {
99         struct_sg_io_hdr sg_io;
100
101         if (umove(tcp, arg, &sg_io) < 0) {
102                 tprints(", ???");
103                 return RVAL_DECODED | 1;
104         }
105
106         if (sg_io.interface_id != (unsigned char) 'S') {
107                 tprintf(" => interface_id=%u", sg_io.interface_id);
108                 return RVAL_DECODED | 1;
109         }
110
111         if (sg_io.dxfer_direction == SG_DXFER_FROM_DEV ||
112             sg_io.dxfer_direction == SG_DXFER_TO_FROM_DEV) {
113                 uint32_t din_len = sg_io.dxfer_len;
114
115                 if (sg_io.resid > 0)
116                         din_len -= sg_io.resid;
117                 tprintf(", data[%u]=", din_len);
118                 if (sg_io.iovec_count)
119                         tprint_iov_upto(tcp, sg_io.iovec_count,
120                                         ptr_to_kulong(sg_io.dxferp),
121                                         syserror(tcp) ? IOV_DECODE_ADDR :
122                                         IOV_DECODE_STR, din_len);
123                 else
124                         print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.dxferp),
125                                            din_len);
126         }
127         tprintf(", status=%02x", sg_io.status);
128         tprintf(", masked_status=%02x", sg_io.masked_status);
129         tprintf(", sb[%u]=", sg_io.sb_len_wr);
130         print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.sbp), sg_io.sb_len_wr);
131         tprintf(", host_status=%#x", sg_io.host_status);
132         tprintf(", driver_status=%#x", sg_io.driver_status);
133         tprintf(", resid=%d", sg_io.resid);
134         tprintf(", duration=%d", sg_io.duration);
135         tprintf(", info=%#x", sg_io.info);
136
137         return RVAL_DECODED | 1;
138 }
139
140 #else /* !HAVE_SCSI_SG_H */
141
142 static int
143 decode_request(struct tcb *const tcp, const kernel_ulong_t arg)
144 {
145         tprints("{interface_id='S', ...}");
146         return RVAL_DECODED | 1;
147 }
148
149 static int
150 decode_response(struct tcb *const tcp, const kernel_ulong_t arg)
151 {
152         return 0;
153 }
154
155 #endif
156
157 MPERS_PRINTER_DECL(int, decode_sg_io_v3,
158                    struct tcb *const tcp, const kernel_ulong_t arg)
159 {
160         return entering(tcp) ? decode_request(tcp, arg)
161                              : decode_response(tcp, arg);
162 }