xref: /minix/minix/usr.bin/trace/ioctl/block.c (revision 0a6a1f1d)
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 *
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
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
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