1
2 #include "inc.h"
3
4 #include <sys/ioctl.h>
5 #include <minix/partition.h>
6 #include <sys/mtio.h>
7
8 const char *
block_ioctl_name(unsigned long req)9 block_ioctl_name(unsigned long req)
10 {
11
12 switch (req) {
13 NAME(BIOCTRACEBUF);
14 NAME(BIOCTRACECTL);
15 NAME(BIOCTRACEGET); /* big IOCTL, not printing argument */
16 NAME(DIOCSETP);
17 NAME(DIOCGETP);
18 NAME(DIOCEJECT); /* no argument */
19 NAME(DIOCTIMEOUT);
20 NAME(DIOCOPENCT);
21 NAME(DIOCFLUSH); /* no argument */
22 NAME(DIOCGETWC);
23 NAME(DIOCSETWC);
24 NAME(FBDCADDRULE);
25 NAME(FBDCDELRULE);
26 NAME(FBDCGETRULE);
27 NAME(MIOCRAMSIZE);
28 NAME(MTIOCGET); /* TODO: print argument */
29 NAME(MTIOCTOP); /* TODO: print argument */
30 NAME(VNDIOCCLR);
31 NAME(VNDIOCGET);
32 NAME(VNDIOCSET);
33 }
34
35 return NULL;
36 }
37
38 static const struct flags fbd_flags[] = {
39 FLAG(FBD_FLAG_READ),
40 FLAG(FBD_FLAG_WRITE),
41 };
42
43 static void
put_fbd_action(struct trace_proc * proc,const char * name,int action)44 put_fbd_action(struct trace_proc * proc, const char * name, int action)
45 {
46 const char *text = NULL;
47
48 if (!valuesonly) {
49 switch (action) {
50 TEXT(FBD_ACTION_CORRUPT);
51 TEXT(FBD_ACTION_ERROR);
52 TEXT(FBD_ACTION_MISDIR);
53 TEXT(FBD_ACTION_LOSTTORN);
54 }
55 }
56
57 if (text != NULL)
58 put_field(proc, name, text);
59 else
60 put_value(proc, name, "%d", action);
61 }
62
63 static const struct flags vnd_flags[] = {
64 FLAG(VNDIOF_HASGEOM),
65 FLAG(VNDIOF_READONLY),
66 FLAG(VNDIOF_FORCE),
67 };
68
69 int
block_ioctl_arg(struct trace_proc * proc,unsigned long req,void * ptr,int dir)70 block_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr,
71 int dir)
72 {
73 struct part_geom *part;
74 struct fbd_rule *rule;
75 struct vnd_ioctl *vnd;
76 struct vnd_user *vnu;
77 int i;
78
79 switch (req) {
80 case BIOCTRACEBUF:
81 if (ptr == NULL)
82 return IF_OUT;
83
84 put_value(proc, NULL, "%zu", *(size_t *)ptr);
85 return IF_ALL;
86
87 case BIOCTRACECTL:
88 if (ptr == NULL)
89 return IF_OUT;
90
91 i = *(int *)ptr;
92 if (!valuesonly && i == BTCTL_START)
93 put_field(proc, NULL, "BTCTL_START");
94 else if (!valuesonly && i == BTCTL_STOP)
95 put_field(proc, NULL, "BTCTL_STOP");
96 else
97 put_value(proc, NULL, "%d", i);
98 return IF_ALL;
99
100 case DIOCSETP:
101 if ((part = (struct part_geom *)ptr) == NULL)
102 return IF_OUT;
103
104 put_value(proc, "base", "%"PRIu64, part->base);
105 put_value(proc, "size", "%"PRIu64, part->size);
106 return IF_ALL;
107
108 case DIOCGETP:
109 if ((part = (struct part_geom *)ptr) == NULL)
110 return IF_IN;
111
112 put_value(proc, "base", "%"PRIu64, part->base);
113 put_value(proc, "size", "%"PRIu64, part->size);
114 if (verbose > 0) {
115 put_value(proc, "cylinders", "%u", part->cylinders);
116 put_value(proc, "heads", "%u", part->heads);
117 put_value(proc, "sectors", "%u", part->sectors);
118 return IF_ALL;
119 } else
120 return 0;
121
122 case DIOCTIMEOUT:
123 /* Print the old timeout only if verbosity is high enough. */
124 if (ptr == NULL)
125 return IF_OUT | ((verbose > 0) ? IF_IN : 0);
126
127 /* Same action for out and in. */
128 put_value(proc, NULL, "%d", *(int *)ptr);
129 return IF_ALL;
130
131 case DIOCOPENCT:
132 if (ptr == NULL)
133 return IF_IN;
134
135 put_value(proc, NULL, "%d", *(int *)ptr);
136 return IF_ALL;
137
138 case DIOCSETWC:
139 case DIOCGETWC:
140 if (ptr == NULL)
141 return dir; /* out or in, depending on the request */
142
143 put_value(proc, NULL, "%d", *(int *)ptr);
144 return IF_ALL;
145
146 case FBDCDELRULE:
147 if (ptr == NULL)
148 return IF_OUT;
149
150 put_value(proc, NULL, "%d", *(fbd_rulenum_t *)ptr);
151 return IF_ALL;
152
153 case FBDCGETRULE:
154 if ((rule = (struct fbd_rule *)ptr) == NULL)
155 return IF_OUT | IF_IN;
156
157 if (dir == IF_OUT) {
158 put_value(proc, "num", "%d", rule->num);
159 return IF_ALL;
160 }
161
162 /*
163 * The returned result is the same as what is passed to the
164 * add request, so we can use the same code to print both.
165 */
166 /* FALLTHROUGH */
167 case FBDCADDRULE:
168 if ((rule = (struct fbd_rule *)ptr) == NULL)
169 return IF_OUT;
170
171 if (rule->start != 0 || rule->end != 0 || verbose > 0) {
172 put_value(proc, "start", "%"PRIu64, rule->start);
173 put_value(proc, "end", "%"PRIu64, rule->end);
174 }
175 if (rule->flags != (FBD_FLAG_READ | FBD_FLAG_WRITE) ||
176 verbose > 0)
177 put_flags(proc, "flags", fbd_flags, COUNT(fbd_flags),
178 "0x%x", rule->flags);
179 if (rule->skip != 0 || verbose > 0)
180 put_value(proc, "skip", "%u", rule->skip);
181 if (rule->count != 0 || verbose > 0)
182 put_value(proc, "count", "%u", rule->count);
183 put_fbd_action(proc, "action", rule->action);
184
185 return 0; /* TODO: optionally print the union fields */
186
187 case MIOCRAMSIZE:
188 if (ptr == NULL)
189 return IF_OUT;
190
191 put_value(proc, NULL, "%"PRIu32, *(u32_t *)ptr);
192 return IF_ALL;
193
194 case VNDIOCSET:
195 if ((vnd = (struct vnd_ioctl *)ptr) == NULL)
196 return IF_OUT | IF_IN;
197
198 if (dir == IF_OUT) {
199 put_value(proc, "vnd_fildes", "%d", vnd->vnd_fildes);
200 put_flags(proc, "vnd_flags", vnd_flags,
201 COUNT(vnd_flags), "0x%x", vnd->vnd_flags);
202 return 0; /* TODO: print geometry if given */
203 } else {
204 put_value(proc, "vnd_size", "%"PRIu64, vnd->vnd_size);
205 return IF_ALL;
206 }
207
208 case VNDIOCCLR:
209 if ((vnd = (struct vnd_ioctl *)ptr) == NULL)
210 return IF_OUT;
211
212 put_flags(proc, "vnd_flags", vnd_flags, COUNT(vnd_flags),
213 "0x%x", vnd->vnd_flags);
214 return IF_ALL;
215
216 case VNDIOCGET:
217 if ((vnu = (struct vnd_user *)ptr) == NULL)
218 return IF_IN;
219
220 put_value(proc, "vnu_unit", "%d", vnu->vnu_unit);
221 put_dev(proc, "vnu_dev", vnu->vnu_dev);
222 put_value(proc, "vnu_ino", "%"PRId64, vnu->vnu_ino);
223 return IF_ALL;
224
225 default:
226 return 0;
227 }
228 }
229