]> granicus.if.org Git - strace/blob - scsi.c
clone: fix print_tls_arg on x86
[strace] / scsi.c
1 /*
2  * Copyright (c) 2007 Vladimir Nadvornik <nadvornik@suse.cz>
3  * Copyright (c) 2007-2018 Dmitry V. Levin <ldv@altlinux.org>
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: LGPL-2.1-or-later
7  */
8
9 #include "defs.h"
10
11 #ifdef HAVE_SCSI_SG_H
12 # include <scsi/sg.h>
13 #endif
14
15 #define XLAT_MACROS_ONLY
16 # include "xlat/scsi_sg_commands.h"
17 #undef XLAT_MACROS_ONLY
18 #include "xlat/sg_scsi_reset.h"
19
20 static int
21 decode_sg_io(struct tcb *const tcp, const uint32_t iid,
22              const kernel_ulong_t arg)
23 {
24         switch (iid) {
25                 case 'S':
26                         return decode_sg_io_v3(tcp, arg);
27                 case 'Q':
28                         return decode_sg_io_v4(tcp, arg);
29                 default:
30                         tprintf("[%u]", iid);
31                         return RVAL_IOCTL_DECODED;
32         }
33
34 }
35
36 #ifdef HAVE_SCSI_SG_H
37
38 static int
39 decode_sg_scsi_id(struct tcb *const tcp, const kernel_ulong_t arg)
40 {
41         struct sg_scsi_id id;
42
43         if (entering(tcp))
44                 return 0;
45
46         tprints(", ");
47         if (!umove_or_printaddr(tcp, arg, &id)) {
48                 tprintf("{host_no=%d"
49                         ", channel=%d"
50                         ", scsi_id=%#x"
51                         ", lun=%d"
52                         ", scsi_type=%#x"
53                         ", h_cmd_per_lun=%hd"
54                         ", d_queue_depth=%hd}",
55                         id.host_no,
56                         id.channel,
57                         id.scsi_id,
58                         id.lun,
59                         id.scsi_type,
60                         id.h_cmd_per_lun,
61                         id.d_queue_depth);
62         }
63         return RVAL_IOCTL_DECODED;
64 }
65
66 #endif /* HAVE_SCSI_SG_H */
67
68 int
69 scsi_ioctl(struct tcb *const tcp, const unsigned int code,
70            const kernel_ulong_t arg)
71 {
72         switch (code) {
73         case SG_IO:
74                 if (entering(tcp)) {
75                         uint32_t iid;
76
77                         tprints(", ");
78                         if (umove_or_printaddr(tcp, arg, &iid)) {
79                                 break;
80                         } else {
81                                 return decode_sg_io(tcp, iid, arg);
82                         }
83                 } else {
84                         uint32_t *piid = get_tcb_priv_data(tcp);
85                         if (piid)
86                                 decode_sg_io(tcp, *piid, arg);
87                         tprints("}");
88                         break;
89                 }
90
91 #ifdef HAVE_SCSI_SG_H
92         /* returns struct sg_scsi_id */
93         case SG_GET_SCSI_ID:
94                 return decode_sg_scsi_id(tcp, arg);
95         /* returns struct sg_req_info */
96         case SG_GET_REQUEST_TABLE:
97                 return decode_sg_req_info(tcp, arg);
98 #endif /* HAVE_SCSI_SG_H */
99
100         /* takes a value by pointer */
101         case SG_SCSI_RESET: {
102                 unsigned int val;
103                 tprints(", ");
104                 if (!umove_or_printaddr(tcp, arg, &val)) {
105                         tprints("[");
106                         if (val & SG_SCSI_RESET_NO_ESCALATE) {
107                                 printxval(sg_scsi_reset,
108                                           SG_SCSI_RESET_NO_ESCALATE, 0);
109                                 tprints("|");
110                         }
111                         printxval(sg_scsi_reset,
112                                   val & ~SG_SCSI_RESET_NO_ESCALATE,
113                                   "SG_SCSI_RESET_???");
114                         tprints("]");
115
116                 }
117                 break;
118         }
119
120         /* takes a signed int by pointer */
121         case SG_NEXT_CMD_LEN:
122         case SG_SET_COMMAND_Q:
123         case SG_SET_DEBUG:
124         case SG_SET_FORCE_LOW_DMA:
125         case SG_SET_FORCE_PACK_ID:
126         case SG_SET_KEEP_ORPHAN:
127         case SG_SET_RESERVED_SIZE:
128         case SG_SET_TIMEOUT:
129                 tprints(", ");
130                 printnum_int(tcp, arg, "%d");
131                 break;
132
133         /* returns a signed int by pointer */
134         case SG_EMULATED_HOST:
135         case SG_GET_ACCESS_COUNT:
136         case SG_GET_COMMAND_Q:
137         case SG_GET_KEEP_ORPHAN:
138         case SG_GET_LOW_DMA:
139         case SG_GET_NUM_WAITING:
140         case SG_GET_PACK_ID:
141         case SG_GET_RESERVED_SIZE:
142         case SG_GET_SG_TABLESIZE:
143         case SG_GET_TRANSFORM:
144         case SG_GET_VERSION_NUM:
145                 if (entering(tcp))
146                         return 0;
147                 tprints(", ");
148                 printnum_int(tcp, arg, "%d");
149                 break;
150
151         /* takes an integer by value */
152         case SG_SET_TRANSFORM:
153                 tprintf(", %#x", (unsigned int) arg);
154                 break;
155
156         /* no arguments */
157         case SG_GET_TIMEOUT:
158                 break;
159
160         default:
161                 return RVAL_DECODED;
162         }
163
164         return RVAL_IOCTL_DECODED;
165 }