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 : : * All rights reserved.
5 : : *
6 : : * Redistribution and use in source and binary forms, with or without
7 : : * modification, are permitted provided that the following conditions
8 : : * are met:
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.
16 : : *
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.
27 : : */
28 : :
29 : : #include "defs.h"
30 : :
31 : : #ifdef HAVE_SCSI_SG_H
32 : : # include <scsi/sg.h>
33 : : #endif
34 : :
35 : : #include "xlat/scsi_sg_commands.h"
36 : : #include "xlat/sg_scsi_reset.h"
37 : :
38 : : static int
39 : 132 : decode_sg_io(struct tcb *const tcp, const uint32_t iid,
40 : : const kernel_ulong_t arg)
41 : : {
42 [ + + + ]: 132 : switch (iid) {
43 : : case 'S':
44 : 90 : return decode_sg_io_v3(tcp, arg);
45 : : case 'Q':
46 : 30 : return decode_sg_io_v4(tcp, arg);
47 : : default:
48 : 12 : tprintf("[%u]", iid);
49 : 12 : return RVAL_DECODED | 1;
50 : : }
51 : :
52 : : }
53 : :
54 : : #ifdef HAVE_SCSI_SG_H
55 : :
56 : : static int
57 : 12 : decode_sg_scsi_id(struct tcb *const tcp, const kernel_ulong_t arg)
58 : : {
59 : : struct sg_scsi_id id;
60 : :
61 [ + + ]: 12 : if (entering(tcp))
62 : 6 : return 0;
63 : :
64 : 6 : tprints(", ");
65 [ - + ]: 6 : if (!umove_or_printaddr(tcp, arg, &id)) {
66 : 0 : tprintf("{host_no=%d"
67 : : ", channel=%d"
68 : : ", scsi_id=%#x"
69 : : ", lun=%d"
70 : : ", scsi_type=%#x"
71 : : ", h_cmd_per_lun=%hd"
72 : : ", d_queue_depth=%hd}",
73 : : id.host_no,
74 : : id.channel,
75 : : id.scsi_id,
76 : : id.lun,
77 : : id.scsi_type,
78 : 0 : id.h_cmd_per_lun,
79 : 0 : id.d_queue_depth);
80 : : }
81 : 12 : return RVAL_DECODED | 1;
82 : : }
83 : :
84 : : #endif /* HAVE_SCSI_SG_H */
85 : :
86 : : int
87 : 600 : scsi_ioctl(struct tcb *const tcp, const unsigned int code,
88 : : const kernel_ulong_t arg)
89 : : {
90 [ + + + + : 600 : switch (code) {
+ + + +
+ ]
91 : : case SG_IO:
92 [ + + ]: 162 : if (entering(tcp)) {
93 : : uint32_t iid;
94 : :
95 : 108 : tprints(", ");
96 [ + + ]: 108 : if (umove_or_printaddr(tcp, arg, &iid)) {
97 : 30 : break;
98 : : } else {
99 : 78 : return decode_sg_io(tcp, iid, arg);
100 : : }
101 : : } else {
102 : 54 : uint32_t *piid = get_tcb_priv_data(tcp);
103 [ + - ]: 54 : if (piid)
104 : 54 : decode_sg_io(tcp, *piid, arg);
105 : 54 : tprints("}");
106 : 54 : break;
107 : : }
108 : :
109 : : #ifdef HAVE_SCSI_SG_H
110 : : /* returns struct sg_scsi_id */
111 : : case SG_GET_SCSI_ID:
112 : 12 : return decode_sg_scsi_id(tcp, arg);
113 : : /* returns struct sg_req_info */
114 : : case SG_GET_REQUEST_TABLE:
115 : 12 : return decode_sg_req_info(tcp, arg);
116 : : #endif /* HAVE_SCSI_SG_H */
117 : :
118 : : /* takes a value by pointer */
119 : : case SG_SCSI_RESET: {
120 : : unsigned int val;
121 : 24 : tprints(", ");
122 [ + + ]: 24 : if (!umove_or_printaddr(tcp, arg, &val)) {
123 : 18 : tprints("[");
124 [ + + ]: 18 : if (val & SG_SCSI_RESET_NO_ESCALATE) {
125 : 6 : printxval(sg_scsi_reset,
126 : : SG_SCSI_RESET_NO_ESCALATE, 0);
127 : 6 : tprints("|");
128 : : }
129 : 18 : printxval(sg_scsi_reset,
130 : : val & ~SG_SCSI_RESET_NO_ESCALATE,
131 : : "SG_SCSI_RESET_???");
132 : 18 : tprints("]");
133 : :
134 : : }
135 : 24 : break;
136 : : }
137 : :
138 : : /* takes a signed int by pointer */
139 : : case SG_NEXT_CMD_LEN:
140 : : case SG_SET_COMMAND_Q:
141 : : case SG_SET_DEBUG:
142 : : case SG_SET_FORCE_LOW_DMA:
143 : : case SG_SET_FORCE_PACK_ID:
144 : : case SG_SET_KEEP_ORPHAN:
145 : : case SG_SET_RESERVED_SIZE:
146 : : case SG_SET_TIMEOUT:
147 : 96 : tprints(", ");
148 : 96 : printnum_int(tcp, arg, "%d");
149 : 96 : break;
150 : :
151 : : /* returns a signed int by pointer */
152 : : case SG_EMULATED_HOST:
153 : : case SG_GET_ACCESS_COUNT:
154 : : case SG_GET_COMMAND_Q:
155 : : case SG_GET_KEEP_ORPHAN:
156 : : case SG_GET_LOW_DMA:
157 : : case SG_GET_NUM_WAITING:
158 : : case SG_GET_PACK_ID:
159 : : case SG_GET_RESERVED_SIZE:
160 : : case SG_GET_SG_TABLESIZE:
161 : : case SG_GET_TRANSFORM:
162 : : case SG_GET_VERSION_NUM:
163 [ + + ]: 264 : if (entering(tcp))
164 : 132 : return 0;
165 : 132 : tprints(", ");
166 : 132 : printnum_int(tcp, arg, "%d");
167 : 132 : break;
168 : :
169 : : /* takes an integer by value */
170 : : case SG_SET_TRANSFORM:
171 : 12 : tprintf(", %#x", (unsigned int) arg);
172 : 12 : break;
173 : :
174 : : /* no arguments */
175 : : case SG_GET_TIMEOUT:
176 : 6 : break;
177 : :
178 : : default:
179 : 12 : return RVAL_DECODED;
180 : : }
181 : :
182 : 354 : return RVAL_DECODED | 1;
183 : : }
|