Branch data Line data Source code
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 : : #include "xlat/sg_io_info.h"
45 : :
46 : : #ifdef HAVE_SCSI_SG_H
47 : : # include "xlat/sg_io_dxfer_direction.h"
48 : : # include "xlat/sg_io_flags.h"
49 : :
50 : : static void
51 : 132 : print_sg_io_buffer(struct tcb *const tcp, const kernel_ulong_t addr,
52 : : const unsigned int data_size, const unsigned int iovec_count)
53 : : {
54 [ + + ]: 132 : if (iovec_count) {
55 : 24 : tprint_iov_upto(tcp, iovec_count, addr, IOV_DECODE_STR,
56 : : data_size);
57 : : } else {
58 : 108 : printstr_ex(tcp, addr, data_size, QUOTE_FORCE_HEX);
59 : : }
60 : 132 : }
61 : :
62 : : static int
63 : 48 : decode_request(struct tcb *const tcp, const kernel_ulong_t arg)
64 : : {
65 : : struct_sg_io_hdr sg_io;
66 : : static const size_t skip_iid =
67 : : offsetof(struct_sg_io_hdr, dxfer_direction);
68 : :
69 : 48 : tprints("{interface_id='S', ");
70 [ + + ]: 48 : if (umoven_or_printaddr(tcp, arg + skip_iid, sizeof(sg_io) - skip_iid,
71 : : &sg_io.dxfer_direction)) {
72 : 6 : tprints("}");
73 : 6 : return RVAL_DECODED | 1;
74 : : }
75 : :
76 : 42 : tprints("dxfer_direction=");
77 : 42 : printxval(sg_io_dxfer_direction, sg_io.dxfer_direction,
78 : : "SG_DXFER_???");
79 : 42 : tprintf(", cmd_len=%u, cmdp=", sg_io.cmd_len);
80 : 42 : print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.cmdp), sg_io.cmd_len, 0);
81 : 42 : tprintf(", mx_sb_len=%d", sg_io.mx_sb_len);
82 : 42 : tprintf(", iovec_count=%d", sg_io.iovec_count);
83 : 42 : tprintf(", dxfer_len=%u", sg_io.dxfer_len);
84 : 42 : tprintf(", timeout=%u", sg_io.timeout);
85 : 42 : tprints(", flags=");
86 : 42 : printflags(sg_io_flags, sg_io.flags, "SG_FLAG_???");
87 : :
88 [ + + ][ + + ]: 42 : if (sg_io.dxfer_direction == SG_DXFER_TO_DEV ||
89 : 30 : sg_io.dxfer_direction == SG_DXFER_TO_FROM_DEV) {
90 : 24 : tprints(", dxferp=");
91 : 24 : print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.dxferp),
92 : 24 : sg_io.dxfer_len, sg_io.iovec_count);
93 : : }
94 : :
95 : 42 : struct_sg_io_hdr *entering_sg_io = malloc(sizeof(*entering_sg_io));
96 [ + - ]: 42 : if (entering_sg_io) {
97 : 42 : memcpy(entering_sg_io, &sg_io, sizeof(sg_io));
98 : 42 : entering_sg_io->interface_id = (unsigned char) 'S';
99 : 42 : set_tcb_priv_data(tcp, entering_sg_io, free);
100 : : }
101 : :
102 : 48 : return 1;
103 : : }
104 : :
105 : : static int
106 : 42 : decode_response(struct tcb *const tcp, const kernel_ulong_t arg)
107 : : {
108 : 42 : struct_sg_io_hdr *entering_sg_io = get_tcb_priv_data(tcp);
109 : : struct_sg_io_hdr sg_io;
110 : :
111 [ - + ]: 42 : if (umove(tcp, arg, &sg_io) < 0) {
112 : : /* print i/o fields fetched on entering syscall */
113 [ # # ]: 0 : if (entering_sg_io->dxfer_direction == SG_DXFER_FROM_DEV) {
114 : 0 : tprints(", dxferp=");
115 : 0 : printaddr(ptr_to_kulong(entering_sg_io->dxferp));
116 : : }
117 : 0 : tprints(", sbp=");
118 : 0 : printaddr(ptr_to_kulong(entering_sg_io->sbp));
119 : 0 : return RVAL_DECODED | 1;
120 : : }
121 : :
122 [ - + ]: 42 : if (sg_io.interface_id != entering_sg_io->interface_id) {
123 : 0 : tprintf(" => interface_id=%u", sg_io.interface_id);
124 : 0 : return RVAL_DECODED | 1;
125 : : }
126 : :
127 [ + + ][ + + ]: 42 : if (sg_io.dxfer_direction == SG_DXFER_FROM_DEV ||
128 : 24 : sg_io.dxfer_direction == SG_DXFER_TO_FROM_DEV) {
129 : 30 : uint32_t din_len = sg_io.dxfer_len;
130 : :
131 [ + + ][ + + ]: 30 : if (sg_io.resid > 0 && (unsigned int) sg_io.resid <= din_len)
132 : 18 : din_len -= sg_io.resid;
133 [ + + ]: 30 : if (sg_io.dxfer_direction == SG_DXFER_FROM_DEV) {
134 : 18 : tprints(", dxferp=");
135 [ + + ]: 12 : } else if (din_len) {
136 : 6 : tprints(" => dxferp=");
137 : : }
138 [ + + ][ + + ]: 30 : if (sg_io.dxfer_direction == SG_DXFER_FROM_DEV || din_len) {
139 : 24 : print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.dxferp),
140 : 24 : din_len, sg_io.iovec_count);
141 : : }
142 : : }
143 : 42 : tprintf(", status=%#x", sg_io.status);
144 : 42 : tprintf(", masked_status=%#x", sg_io.masked_status);
145 : 42 : tprintf(", msg_status=%#x", sg_io.msg_status);
146 : 42 : tprintf(", sb_len_wr=%u, sbp=", sg_io.sb_len_wr);
147 : 42 : print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.sbp), sg_io.sb_len_wr, 0);
148 : 42 : tprintf(", host_status=%#x", sg_io.host_status);
149 : 42 : tprintf(", driver_status=%#x", sg_io.driver_status);
150 : 42 : tprintf(", resid=%d", sg_io.resid);
151 : 42 : tprintf(", duration=%u", sg_io.duration);
152 : 42 : tprints(", info=");
153 : 42 : printflags(sg_io_info, sg_io.info, "SG_INFO_???");
154 : :
155 : 42 : return RVAL_DECODED | 1;
156 : : }
157 : :
158 : : #else /* !HAVE_SCSI_SG_H */
159 : :
160 : : static int
161 : : decode_request(struct tcb *const tcp, const kernel_ulong_t arg)
162 : : {
163 : : tprints("{interface_id='S', ...}");
164 : : return RVAL_DECODED | 1;
165 : : }
166 : :
167 : : static int
168 : : decode_response(struct tcb *const tcp, const kernel_ulong_t arg)
169 : : {
170 : : return 0;
171 : : }
172 : :
173 : : #endif
174 : :
175 : 90 : MPERS_PRINTER_DECL(int, decode_sg_io_v3,
176 : : struct tcb *const tcp, const kernel_ulong_t arg)
177 : : {
178 : 90 : return entering(tcp) ? decode_request(tcp, arg)
179 [ + + ]: 90 : : decode_response(tcp, arg);
180 : : }
|