2 * Copyright (c) 2007 Vladimir Nadvornik <nadvornik@suse.cz>
3 * Copyright (c) 2007 Dmitry V. Levin <ldv@altlinux.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 # include <linux/ioctl.h>
36 # include "xlat/sg_io_dxfer_direction.h"
38 # ifdef HAVE_LINUX_BSG_H
39 # include <linux/bsg.h>
41 # include "xlat/bsg_protocol.h"
42 # include "xlat/bsg_subprotocol.h"
46 print_uchar(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
48 tprintf("%02x", (unsigned int) (* (unsigned char *) elem_buf));
54 print_sg_io_buffer(struct tcb *const tcp, const kernel_ureg_t addr,
55 const unsigned int len)
59 print_array(tcp, addr, len, &buf, sizeof(buf),
60 umoven_or_printaddr, print_uchar, 0);
64 print_sg_io_v3_req(struct tcb *const tcp, const kernel_ureg_t arg)
66 struct sg_io_hdr sg_io;
68 if (umove(tcp, arg, &sg_io) < 0) {
70 return RVAL_DECODED | 1;
73 printxval(sg_io_dxfer_direction, sg_io.dxfer_direction,
75 tprintf(", cmd[%u]=", sg_io.cmd_len);
76 print_sg_io_buffer(tcp, (kernel_ureg_t) sg_io.cmdp, sg_io.cmd_len);
77 tprintf(", mx_sb_len=%d", sg_io.mx_sb_len);
78 tprintf(", iovec_count=%d", sg_io.iovec_count);
79 tprintf(", dxfer_len=%u", sg_io.dxfer_len);
80 tprintf(", timeout=%u", sg_io.timeout);
81 tprintf(", flags=%#x", sg_io.flags);
83 if (sg_io.dxfer_direction == SG_DXFER_TO_DEV ||
84 sg_io.dxfer_direction == SG_DXFER_TO_FROM_DEV) {
85 tprintf(", data[%u]=", sg_io.dxfer_len);
86 if (sg_io.iovec_count)
87 tprint_iov_upto(tcp, sg_io.iovec_count,
88 (kernel_ureg_t) sg_io.dxferp,
92 print_sg_io_buffer(tcp, (kernel_ureg_t) sg_io.dxferp,
99 print_sg_io_v3_res(struct tcb *const tcp, const kernel_ureg_t arg)
101 struct sg_io_hdr sg_io;
103 if (umove(tcp, arg, &sg_io) < 0) {
108 if (sg_io.dxfer_direction == SG_DXFER_FROM_DEV ||
109 sg_io.dxfer_direction == SG_DXFER_TO_FROM_DEV) {
110 uint32_t din_len = sg_io.dxfer_len;
113 din_len -= sg_io.resid;
114 tprintf(", data[%u]=", din_len);
115 if (sg_io.iovec_count)
116 tprint_iov_upto(tcp, sg_io.iovec_count,
117 (kernel_ureg_t) sg_io.dxferp,
118 syserror(tcp) ? IOV_DECODE_ADDR :
119 IOV_DECODE_STR, din_len);
121 print_sg_io_buffer(tcp, (kernel_ureg_t) sg_io.dxferp,
124 tprintf(", status=%02x", sg_io.status);
125 tprintf(", masked_status=%02x", sg_io.masked_status);
126 tprintf(", sb[%u]=", sg_io.sb_len_wr);
127 print_sg_io_buffer(tcp, (kernel_ureg_t) sg_io.sbp, sg_io.sb_len_wr);
128 tprintf(", host_status=%#x", sg_io.host_status);
129 tprintf(", driver_status=%#x", sg_io.driver_status);
130 tprintf(", resid=%d", sg_io.resid);
131 tprintf(", duration=%d", sg_io.duration);
132 tprintf(", info=%#x", sg_io.info);
135 #ifdef HAVE_LINUX_BSG_H
138 print_sg_io_v4_req(struct tcb *const tcp, const kernel_ureg_t arg)
140 struct sg_io_v4 sg_io;
142 if (umove(tcp, arg, &sg_io) < 0) {
144 return RVAL_DECODED | 1;
147 printxval(bsg_protocol, sg_io.protocol, "BSG_PROTOCOL_???");
149 printxval(bsg_subprotocol, sg_io.subprotocol, "BSG_SUB_PROTOCOL_???");
150 tprintf(", request[%u]=", sg_io.request_len);
151 print_sg_io_buffer(tcp, sg_io.request, sg_io.request_len);
152 tprintf(", request_tag=%" PRI__u64, sg_io.request_tag);
153 tprintf(", request_attr=%u", sg_io.request_attr);
154 tprintf(", request_priority=%u", sg_io.request_priority);
155 tprintf(", request_extra=%u", sg_io.request_extra);
156 tprintf(", max_response_len=%u", sg_io.max_response_len);
158 tprintf(", dout_iovec_count=%u", sg_io.dout_iovec_count);
159 tprintf(", dout_xfer_len=%u", sg_io.dout_xfer_len);
160 tprintf(", din_iovec_count=%u", sg_io.din_iovec_count);
161 tprintf(", din_xfer_len=%u", sg_io.din_xfer_len);
162 tprintf(", timeout=%u", sg_io.timeout);
163 tprintf(", flags=%u", sg_io.flags);
164 tprintf(", usr_ptr=%" PRI__u64, sg_io.usr_ptr);
165 tprintf(", spare_in=%u", sg_io.spare_in);
166 tprintf(", dout[%u]=", sg_io.dout_xfer_len);
167 if (sg_io.dout_iovec_count)
168 tprint_iov_upto(tcp, sg_io.dout_iovec_count, sg_io.dout_xferp,
169 IOV_DECODE_STR, sg_io.dout_xfer_len);
171 print_sg_io_buffer(tcp, sg_io.dout_xferp, sg_io.dout_xfer_len);
176 print_sg_io_v4_res(struct tcb *const tcp, const kernel_ureg_t arg)
178 struct sg_io_v4 sg_io;
181 if (umove(tcp, arg, &sg_io) < 0) {
186 tprintf(", response[%u]=", sg_io.response_len);
187 print_sg_io_buffer(tcp, sg_io.response, sg_io.response_len);
188 din_len = sg_io.din_xfer_len;
189 if (sg_io.din_resid > 0)
190 din_len -= sg_io.din_resid;
191 tprintf(", din[%u]=", din_len);
192 if (sg_io.din_iovec_count)
193 tprint_iov_upto(tcp, sg_io.din_iovec_count, sg_io.din_xferp,
194 syserror(tcp) ? IOV_DECODE_ADDR :
195 IOV_DECODE_STR, din_len);
197 print_sg_io_buffer(tcp, sg_io.din_xferp, din_len);
198 tprintf(", driver_status=%u", sg_io.driver_status);
199 tprintf(", transport_status=%u", sg_io.transport_status);
200 tprintf(", device_status=%u", sg_io.device_status);
201 tprintf(", retry_delay=%u", sg_io.retry_delay);
202 tprintf(", info=%u", sg_io.info);
203 tprintf(", duration=%u", sg_io.duration);
204 tprintf(", response_len=%u", sg_io.response_len);
205 tprintf(", din_resid=%u", sg_io.din_resid);
206 tprintf(", dout_resid=%u", sg_io.dout_resid);
207 tprintf(", generated_tag=%" PRI__u64, sg_io.generated_tag);
208 tprintf(", spare_out=%u", sg_io.spare_out);
211 #else /* !HAVE_LINUX_BSG_H */
214 print_sg_io_v4_req(struct tcb *const tcp, const kernel_ureg_t arg)
217 return RVAL_DECODED | 1;
221 print_sg_io_v4_res(struct tcb *const tcp, const kernel_ureg_t arg)
228 print_sg_io_req(struct tcb *const tcp, const uint32_t iid,
229 const kernel_ureg_t arg)
231 tprintf("{'%c', ", iid);
235 return print_sg_io_v3_req(tcp, arg);
237 return print_sg_io_v4_req(tcp, arg);
240 return RVAL_DECODED | 1;
246 print_sg_io_res(struct tcb *const tcp, const uint32_t iid,
247 const kernel_ureg_t arg)
251 print_sg_io_v3_res(tcp, arg);
254 print_sg_io_v4_res(tcp, arg);
260 scsi_ioctl(struct tcb *const tcp, const unsigned int code,
261 const kernel_ureg_t arg)
270 if (umove_or_printaddr(tcp, arg, &iid)) {
271 return RVAL_DECODED | 1;
273 return print_sg_io_req(tcp, iid, arg);
276 if (!syserror(tcp)) {
277 if (umove(tcp, arg, &iid) < 0)
280 print_sg_io_res(tcp, iid, arg);
283 return RVAL_DECODED | 1;
287 #endif /* HAVE_SCSI_SG_H */