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 *tcp, const unsigned long addr, const unsigned int len)
58 print_array(tcp, addr, len, &buf, sizeof(buf),
59 umoven_or_printaddr, print_uchar, 0);
63 print_sg_io_v3_req(struct tcb *tcp, const long arg)
65 struct sg_io_hdr sg_io;
67 if (umove(tcp, arg, &sg_io) < 0) {
69 return RVAL_DECODED | 1;
72 printxval(sg_io_dxfer_direction, sg_io.dxfer_direction,
74 tprintf(", cmd[%u]=", sg_io.cmd_len);
75 print_sg_io_buffer(tcp, (unsigned long) sg_io.cmdp, sg_io.cmd_len);
76 tprintf(", mx_sb_len=%d", sg_io.mx_sb_len);
77 tprintf(", iovec_count=%d", sg_io.iovec_count);
78 tprintf(", dxfer_len=%u", sg_io.dxfer_len);
79 tprintf(", timeout=%u", sg_io.timeout);
80 tprintf(", flags=%#x", sg_io.flags);
82 if (sg_io.dxfer_direction == SG_DXFER_TO_DEV ||
83 sg_io.dxfer_direction == SG_DXFER_TO_FROM_DEV) {
84 tprintf(", data[%u]=", sg_io.dxfer_len);
85 if (sg_io.iovec_count)
86 tprint_iov_upto(tcp, sg_io.iovec_count,
87 (unsigned long) sg_io.dxferp,
91 print_sg_io_buffer(tcp, (unsigned long) sg_io.dxferp,
98 print_sg_io_v3_res(struct tcb *tcp, const long arg)
100 struct sg_io_hdr sg_io;
102 if (umove(tcp, arg, &sg_io) < 0) {
107 if (sg_io.dxfer_direction == SG_DXFER_FROM_DEV ||
108 sg_io.dxfer_direction == SG_DXFER_TO_FROM_DEV) {
109 uint32_t din_len = sg_io.dxfer_len;
112 din_len -= sg_io.resid;
113 tprintf(", data[%u]=", din_len);
114 if (sg_io.iovec_count)
115 tprint_iov_upto(tcp, sg_io.iovec_count,
116 (unsigned long) sg_io.dxferp,
120 print_sg_io_buffer(tcp, (unsigned long) sg_io.dxferp,
123 tprintf(", status=%02x", sg_io.status);
124 tprintf(", masked_status=%02x", sg_io.masked_status);
125 tprintf(", sb[%u]=", sg_io.sb_len_wr);
126 print_sg_io_buffer(tcp, (unsigned long) sg_io.sbp, sg_io.sb_len_wr);
127 tprintf(", host_status=%#x", sg_io.host_status);
128 tprintf(", driver_status=%#x", sg_io.driver_status);
129 tprintf(", resid=%d", sg_io.resid);
130 tprintf(", duration=%d", sg_io.duration);
131 tprintf(", info=%#x", sg_io.info);
134 #ifdef HAVE_LINUX_BSG_H
137 print_sg_io_v4_req(struct tcb *tcp, const long arg)
139 struct sg_io_v4 sg_io;
141 if (umove(tcp, arg, &sg_io) < 0) {
143 return RVAL_DECODED | 1;
146 printxval(bsg_protocol, sg_io.protocol, "BSG_PROTOCOL_???");
148 printxval(bsg_subprotocol, sg_io.subprotocol, "BSG_SUB_PROTOCOL_???");
149 tprintf(", request[%u]=", sg_io.request_len);
150 print_sg_io_buffer(tcp, sg_io.request, sg_io.request_len);
151 tprintf(", request_tag=%" PRI__u64, sg_io.request_tag);
152 tprintf(", request_attr=%u", sg_io.request_attr);
153 tprintf(", request_priority=%u", sg_io.request_priority);
154 tprintf(", request_extra=%u", sg_io.request_extra);
155 tprintf(", max_response_len=%u", sg_io.max_response_len);
157 tprintf(", dout_iovec_count=%u", sg_io.dout_iovec_count);
158 tprintf(", dout_xfer_len=%u", sg_io.dout_xfer_len);
159 tprintf(", din_iovec_count=%u", sg_io.din_iovec_count);
160 tprintf(", din_xfer_len=%u", sg_io.din_xfer_len);
161 tprintf(", timeout=%u", sg_io.timeout);
162 tprintf(", flags=%u", sg_io.flags);
163 tprintf(", usr_ptr=%" PRI__u64, sg_io.usr_ptr);
164 tprintf(", spare_in=%u", sg_io.spare_in);
165 tprintf(", dout[%u]=", sg_io.dout_xfer_len);
166 if (sg_io.dout_iovec_count)
167 tprint_iov_upto(tcp, sg_io.dout_iovec_count, sg_io.dout_xferp,
168 IOV_DECODE_STR, sg_io.dout_xfer_len);
170 print_sg_io_buffer(tcp, sg_io.dout_xferp, sg_io.dout_xfer_len);
175 print_sg_io_v4_res(struct tcb *tcp, const long arg)
177 struct sg_io_v4 sg_io;
180 if (umove(tcp, arg, &sg_io) < 0) {
185 tprintf(", response[%u]=", sg_io.response_len);
186 print_sg_io_buffer(tcp, sg_io.response, sg_io.response_len);
187 din_len = sg_io.din_xfer_len;
188 if (sg_io.din_resid > 0)
189 din_len -= sg_io.din_resid;
190 tprintf(", din[%u]=", din_len);
191 if (sg_io.din_iovec_count)
192 tprint_iov_upto(tcp, sg_io.din_iovec_count, sg_io.din_xferp,
193 IOV_DECODE_STR, din_len);
195 print_sg_io_buffer(tcp, sg_io.din_xferp, din_len);
196 tprintf(", driver_status=%u", sg_io.driver_status);
197 tprintf(", transport_status=%u", sg_io.transport_status);
198 tprintf(", device_status=%u", sg_io.device_status);
199 tprintf(", retry_delay=%u", sg_io.retry_delay);
200 tprintf(", info=%u", sg_io.info);
201 tprintf(", duration=%u", sg_io.duration);
202 tprintf(", response_len=%u", sg_io.response_len);
203 tprintf(", din_resid=%u", sg_io.din_resid);
204 tprintf(", dout_resid=%u", sg_io.dout_resid);
205 tprintf(", generated_tag=%" PRI__u64, sg_io.generated_tag);
206 tprintf(", spare_out=%u", sg_io.spare_out);
209 #else /* !HAVE_LINUX_BSG_H */
212 print_sg_io_v4_req(struct tcb *tcp, const long arg)
215 return RVAL_DECODED | 1;
219 print_sg_io_v4_res(struct tcb *tcp, const long arg)
226 print_sg_io_req(struct tcb *tcp, uint32_t iid, const long arg)
228 tprintf("{'%c', ", iid);
232 return print_sg_io_v3_req(tcp, arg);
234 return print_sg_io_v4_req(tcp, arg);
237 return RVAL_DECODED | 1;
243 print_sg_io_res(struct tcb *tcp, uint32_t iid, const long arg)
247 print_sg_io_v3_res(tcp, arg);
250 print_sg_io_v4_res(tcp, arg);
256 scsi_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
265 if (!arg || umove(tcp, arg, &iid) < 0) {
267 return RVAL_DECODED | 1;
269 return print_sg_io_req(tcp, iid, arg);
272 if (!syserror(tcp)) {
273 if (umove(tcp, arg, &iid) < 0)
276 print_sg_io_res(tcp, iid, arg);
279 return RVAL_DECODED | 1;
283 #endif /* HAVE_SCSI_SG_H */