Drop main() prototype. Syncs with NetBSD-8
[minix.git] / minix / usr.bin / trace / ioctl / char.c
bloba8ac00d0f69af7ede2edca7e9b218f1e9f6d4666
2 #include "inc.h"
4 #include <dev/pci/pciio.h>
6 #include <minix/fb.h>
7 #include <minix/i2c.h>
8 #include <minix/keymap.h>
9 #include <minix/sound.h>
11 #include <sys/fcntl.h>
12 #include <sys/ioctl.h>
13 #include <sys/kbdio.h>
14 #include <sys/termios.h>
15 #include <sys/time.h>
17 const char *
18 char_ioctl_name(unsigned long req)
21 switch (req) {
22 NAME(MINIX_I2C_IOCTL_EXEC);
23 NAME(FBIOGET_VSCREENINFO);
24 NAME(FBIOPUT_VSCREENINFO);
25 NAME(FBIOGET_FSCREENINFO); /* TODO: print argument */
26 NAME(FBIOPAN_DISPLAY);
27 NAME(DSPIORATE);
28 NAME(DSPIOSTEREO);
29 NAME(DSPIOSIZE);
30 NAME(DSPIOBITS);
31 NAME(DSPIOSIGN);
32 NAME(DSPIOMAX);
33 NAME(DSPIORESET); /* no argument */
34 NAME(DSPIOFREEBUF);
35 NAME(DSPIOSAMPLESINBUF);
36 NAME(DSPIOPAUSE); /* no argument */
37 NAME(DSPIORESUME); /* no argument */
38 NAME(MIXIOGETVOLUME);
39 NAME(MIXIOGETINPUTLEFT);
40 NAME(MIXIOGETINPUTRIGHT);
41 NAME(MIXIOGETOUTPUT);
42 NAME(MIXIOSETVOLUME);
43 NAME(MIXIOSETINPUTLEFT);
44 NAME(MIXIOSETINPUTRIGHT);
45 NAME(MIXIOSETOUTPUT);
46 NAME(TIOCEXCL); /* no argument */
47 NAME(TIOCNXCL); /* no argument */
48 NAME(TIOCFLUSH);
49 NAME(TIOCGETA);
50 NAME(TIOCSETA);
51 NAME(TIOCSETAW);
52 NAME(TIOCSETAF);
53 NAME(TIOCGETD);
54 NAME(TIOCSETD);
55 NAME(TIOCGLINED);
56 NAME(TIOCSLINED);
57 NAME(TIOCSBRK); /* no argument */
58 NAME(TIOCCBRK); /* no argument */
59 NAME(TIOCSDTR); /* no argument */
60 NAME(TIOCCDTR); /* no argument */
61 NAME(TIOCGPGRP);
62 NAME(TIOCSPGRP);
63 NAME(TIOCOUTQ);
64 NAME(TIOCSTI);
65 NAME(TIOCNOTTY); /* no argument */
66 NAME(TIOCPKT);
67 NAME(TIOCSTOP); /* no argument */
68 NAME(TIOCSTART); /* no argument */
69 NAME(TIOCMSET); /* TODO: print argument */
70 NAME(TIOCMBIS); /* TODO: print argument */
71 NAME(TIOCMBIC); /* TODO: print argument */
72 NAME(TIOCMGET); /* TODO: print argument */
73 NAME(TIOCREMOTE);
74 NAME(TIOCGWINSZ);
75 NAME(TIOCSWINSZ);
76 NAME(TIOCUCNTL);
77 NAME(TIOCSTAT);
78 NAME(TIOCGSID);
79 NAME(TIOCCONS);
80 NAME(TIOCSCTTY); /* no argument */
81 NAME(TIOCEXT);
82 NAME(TIOCSIG); /* no argument */
83 NAME(TIOCDRAIN); /* no argument */
84 NAME(TIOCGFLAGS); /* TODO: print argument */
85 NAME(TIOCSFLAGS); /* TODO: print argument */
86 NAME(TIOCDCDTIMESTAMP); /* TODO: print argument */
87 NAME(TIOCRCVFRAME); /* TODO: print argument */
88 NAME(TIOCXMTFRAME); /* TODO: print argument */
89 NAME(TIOCPTMGET); /* TODO: print argument */
90 NAME(TIOCGRANTPT); /* no argument */
91 NAME(TIOCPTSNAME); /* TODO: print argument */
92 NAME(TIOCSQSIZE);
93 NAME(TIOCGQSIZE);
94 NAME(TIOCSFON); /* big IOCTL, not printing argument */
95 NAME(KIOCBELL);
96 NAME(KIOCSLEDS);
97 NAME(KIOCSMAP); /* not worth interpreting */
98 NAME(PCI_IOC_CFGREAD);
99 NAME(PCI_IOC_CFGWRITE);
100 NAME(PCI_IOC_BDF_CFGREAD);
101 NAME(PCI_IOC_BDF_CFGWRITE);
102 NAME(PCI_IOC_BUSINFO);
103 NAME(PCI_IOC_MAP);
104 NAME(PCI_IOC_UNMAP);
105 NAME(PCI_IOC_RESERVE);
106 NAME(PCI_IOC_RELEASE);
109 return NULL;
112 static void
113 put_i2c_op(struct trace_proc * proc, const char *name, i2c_op_t op)
115 const char *text = NULL;
117 if (!valuesonly) {
118 switch (op) {
119 TEXT(I2C_OP_READ);
120 TEXT(I2C_OP_READ_WITH_STOP);
121 TEXT(I2C_OP_WRITE);
122 TEXT(I2C_OP_WRITE_WITH_STOP);
123 TEXT(I2C_OP_READ_BLOCK);
124 TEXT(I2C_OP_WRITE_BLOCK);
128 if (text != NULL)
129 put_field(proc, name, text);
130 else
131 put_value(proc, name, "%d", op);
134 static void
135 put_sound_device(struct trace_proc * proc, const char * name, int device)
137 const char *text = NULL;
139 if (!valuesonly) {
140 switch (device) {
141 TEXT(Master);
142 TEXT(Dac);
143 TEXT(Fm);
144 TEXT(Cd);
145 TEXT(Line);
146 TEXT(Mic);
147 TEXT(Speaker);
148 TEXT(Treble);
149 TEXT(Bass);
153 if (text != NULL)
154 put_field(proc, name, text);
155 else
156 put_value(proc, name, "%d", device);
159 static void
160 put_sound_state(struct trace_proc * proc, const char * name, int state)
163 if (!valuesonly && state == ON)
164 put_field(proc, name, "ON");
165 else if (!valuesonly && state == OFF)
166 put_field(proc, name, "OFF");
167 else
168 put_value(proc, name, "%d", state);
171 static const struct flags flush_flags[] = {
172 FLAG(FREAD),
173 FLAG(FWRITE),
176 static const struct flags tc_iflags[] = {
177 FLAG(IGNBRK),
178 FLAG(BRKINT),
179 FLAG(IGNPAR),
180 FLAG(PARMRK),
181 FLAG(INPCK),
182 FLAG(ISTRIP),
183 FLAG(INLCR),
184 FLAG(IGNCR),
185 FLAG(ICRNL),
186 FLAG(IXON),
187 FLAG(IXOFF),
188 FLAG(IXANY),
189 FLAG(IMAXBEL),
192 static const struct flags tc_oflags[] = {
193 FLAG(OPOST),
194 FLAG(ONLCR),
195 FLAG(OXTABS),
196 FLAG(ONOEOT),
197 FLAG(OCRNL),
198 FLAG(ONOCR),
199 FLAG(ONLRET),
202 static const struct flags tc_cflags[] = {
203 FLAG(CIGNORE),
204 FLAG_MASK(CSIZE, CS5),
205 FLAG_MASK(CSIZE, CS6),
206 FLAG_MASK(CSIZE, CS7),
207 FLAG_MASK(CSIZE, CS8),
208 FLAG(CSTOPB),
209 FLAG(CREAD),
210 FLAG(PARENB),
211 FLAG(PARODD),
212 FLAG(HUPCL),
213 FLAG(CLOCAL),
214 FLAG(CRTSCTS),
215 FLAG(CDTRCTS),
216 FLAG(MDMBUF),
219 static const struct flags tc_lflags[] = {
220 FLAG(ECHOKE),
221 FLAG(ECHOE),
222 FLAG(ECHOK),
223 FLAG(ECHO),
224 FLAG(ECHONL),
225 FLAG(ECHOPRT),
226 FLAG(ECHOCTL),
227 FLAG(ISIG),
228 FLAG(ICANON),
229 FLAG(ALTWERASE),
230 FLAG(IEXTEN),
231 FLAG(EXTPROC),
232 FLAG(TOSTOP),
233 FLAG(FLUSHO),
234 FLAG(NOKERNINFO),
235 FLAG(PENDIN),
236 FLAG(NOFLSH),
239 static void
240 put_tty_disc(struct trace_proc * proc, const char * name, int disc)
242 const char *text = NULL;
244 if (!valuesonly) {
245 switch (disc) {
246 TEXT(TTYDISC);
247 TEXT(TABLDISC);
248 TEXT(SLIPDISC);
249 TEXT(PPPDISC);
250 TEXT(STRIPDISC);
251 TEXT(HDLCDISC);
255 if (text != NULL)
256 put_field(proc, name, text);
257 else
258 put_value(proc, name, "%d", disc);
261 static const struct flags kbd_leds[] = {
262 FLAG(KBD_LEDS_NUM),
263 FLAG(KBD_LEDS_CAPS),
264 FLAG(KBD_LEDS_SCROLL),
268 char_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr,
269 int dir)
271 minix_i2c_ioctl_exec_t *iie;
272 struct fb_var_screeninfo *fbvs;
273 struct volume_level *level;
274 struct inout_ctrl *inout;
275 struct termios *tc;
276 struct ptmget *pm;
277 struct winsize *ws;
278 struct kio_bell *bell;
279 struct kio_leds *leds;
280 struct pciio_cfgreg *pci_cfgreg;
281 struct pciio_bdf_cfgreg *pci_bdf_cfgreg;
282 struct pciio_businfo *pci_businfo;
283 struct pciio_map *pci_iomap;
284 struct pciio_acl *pci_acl;
286 switch (req) {
287 case MINIX_I2C_IOCTL_EXEC:
288 if ((iie = (minix_i2c_ioctl_exec_t *)ptr) == NULL)
289 return IF_OUT; /* we print only the request for now */
291 put_i2c_op(proc, "iie_op", iie->iie_op);
292 put_value(proc, "iie_addr", "0x%04x", iie->iie_addr);
293 return 0; /* TODO: print command/data/result */
295 case FBIOGET_VSCREENINFO:
296 if ((fbvs = (struct fb_var_screeninfo *)ptr) == NULL)
297 return IF_IN;
299 put_value(proc, "xres", "%"PRIu32, fbvs->xres);
300 put_value(proc, "yres", "%"PRIu32, fbvs->yres);
301 put_value(proc, "xres_virtual", "%"PRIu32, fbvs->xres_virtual);
302 put_value(proc, "yres_virtual", "%"PRIu32, fbvs->yres_virtual);
303 put_value(proc, "xoffset", "%"PRIu32, fbvs->xoffset);
304 put_value(proc, "yoffset", "%"PRIu32, fbvs->yoffset);
305 put_value(proc, "bits_per_pixel", "%"PRIu32,
306 fbvs->bits_per_pixel);
307 return 0;
309 case FBIOPUT_VSCREENINFO:
310 case FBIOPAN_DISPLAY:
311 if ((fbvs = (struct fb_var_screeninfo *)ptr) == NULL)
312 return IF_OUT;
314 put_value(proc, "xoffset", "%"PRIu32, fbvs->xoffset);
315 put_value(proc, "yoffset", "%"PRIu32, fbvs->yoffset);
316 return 0;
318 case DSPIORATE:
319 case DSPIOSTEREO:
320 case DSPIOSIZE:
321 case DSPIOBITS:
322 case DSPIOSIGN:
323 case DSPIOMAX:
324 case DSPIOFREEBUF:
325 case DSPIOSAMPLESINBUF:
326 if (ptr == NULL)
327 return dir;
329 put_value(proc, NULL, "%u", *(unsigned int *)ptr);
330 return IF_ALL;
332 case MIXIOGETVOLUME:
333 if ((level = (struct volume_level *)ptr) == NULL)
334 return dir;
336 if (dir == IF_OUT)
337 put_sound_device(proc, "device", level->device);
338 else {
339 put_value(proc, "left", "%d", level->left);
340 put_value(proc, "right", "%d", level->right);
342 return IF_ALL;
344 case MIXIOSETVOLUME:
345 /* Print the corrected volume levels only with verbosity on. */
346 if ((level = (struct volume_level *)ptr) == NULL)
347 return IF_OUT | ((verbose > 0) ? IF_IN : 0);
349 if (dir == IF_OUT)
350 put_sound_device(proc, "device", level->device);
351 put_value(proc, "left", "%d", level->left);
352 put_value(proc, "right", "%d", level->right);
353 return IF_ALL;
355 case MIXIOGETINPUTLEFT:
356 case MIXIOGETINPUTRIGHT:
357 case MIXIOGETOUTPUT:
358 if ((inout = (struct inout_ctrl *)ptr) == NULL)
359 return dir;
361 if (dir == IF_OUT)
362 put_sound_device(proc, "device", inout->device);
363 else {
364 put_sound_state(proc, "left", inout->left);
365 put_sound_state(proc, "right", inout->right);
367 return IF_ALL;
369 case MIXIOSETINPUTLEFT:
370 case MIXIOSETINPUTRIGHT:
371 case MIXIOSETOUTPUT:
372 if ((inout = (struct inout_ctrl *)ptr) == NULL)
373 return IF_OUT;
375 put_sound_device(proc, "device", inout->device);
376 put_sound_state(proc, "left", inout->left);
377 put_sound_state(proc, "right", inout->right);
378 return IF_ALL;
380 case TIOCFLUSH:
381 if (ptr == NULL)
382 return IF_OUT;
384 put_flags(proc, NULL, flush_flags, COUNT(flush_flags), "0x%x",
385 *(int *)ptr);
386 return IF_ALL;
388 case TIOCGETA:
389 case TIOCSETA:
390 case TIOCSETAW:
391 case TIOCSETAF:
392 if ((tc = (struct termios *)ptr) == NULL)
393 return dir;
396 * These are fairly common IOCTLs, so printing everything by
397 * default would create a lot of noise. By default we limit
398 * ourselves to printing the field that contains what I
399 * consider to be the most important flag: ICANON.
400 * TODO: see if we can come up with a decent format for
401 * selectively printing (relatively important) flags.
403 if (verbose > 0) {
404 put_flags(proc, "c_iflag", tc_iflags, COUNT(tc_iflags),
405 "0x%x", tc->c_iflag);
406 put_flags(proc, "c_oflag", tc_oflags, COUNT(tc_oflags),
407 "0x%x", tc->c_oflag);
408 put_flags(proc, "c_cflag", tc_cflags, COUNT(tc_cflags),
409 "0x%x", tc->c_cflag);
411 put_flags(proc, "c_lflag", tc_lflags, COUNT(tc_lflags), "0x%x",
412 tc->c_lflag);
413 if (verbose > 0) {
414 put_value(proc, "c_ispeed", "%d", tc->c_ispeed);
415 put_value(proc, "c_ospeed", "%d", tc->c_ospeed);
417 return 0; /* TODO: print the c_cc fields */
419 case TIOCGETD:
420 case TIOCSETD:
421 if (ptr == NULL)
422 return dir;
424 put_tty_disc(proc, NULL, *(int *)ptr);
425 return IF_ALL;
427 case TIOCGLINED:
428 case TIOCSLINED:
429 if (ptr == NULL)
430 return dir;
432 put_buf(proc, NULL, PF_LOCADDR | PF_STRING, (vir_bytes)ptr,
433 sizeof(linedn_t));
434 return IF_ALL;
436 case TIOCGPGRP:
437 case TIOCSPGRP:
438 case TIOCOUTQ:
439 case TIOCPKT:
440 case TIOCREMOTE:
441 case TIOCUCNTL:
442 case TIOCSTAT: /* argument seems unused? */
443 case TIOCGSID:
444 case TIOCCONS: /* argument seems unused? */
445 case TIOCEXT:
446 case TIOCSQSIZE:
447 case TIOCGQSIZE:
448 /* Print a simple integer. */
449 if (ptr == NULL)
450 return dir;
452 put_value(proc, NULL, "%d", *(int *)ptr);
453 return IF_ALL;
455 case TIOCPTSNAME:
456 if ((pm = (struct ptmget *)ptr) == NULL)
457 return IF_IN;
459 put_buf(proc, "sn", PF_LOCADDR | PF_STRING, (vir_bytes)pm->sn,
460 sizeof(pm->sn));
461 return IF_ALL;
463 case TIOCSTI:
464 if (ptr == NULL)
465 return dir;
467 if (!valuesonly)
468 put_value(proc, NULL, "'%s'",
469 get_escape(*(char *)ptr));
470 else
471 put_value(proc, NULL, "%u", *(char *)ptr);
472 return IF_ALL;
474 case TIOCGWINSZ:
475 case TIOCSWINSZ:
476 if ((ws = (struct winsize *)ptr) == NULL)
477 return dir;
479 /* This is a stupid order, but we follow the struct layout. */
480 put_value(proc, "ws_row", "%u", ws->ws_row);
481 put_value(proc, "ws_col", "%u", ws->ws_col);
482 if (verbose > 0) {
483 put_value(proc, "ws_xpixel", "%u", ws->ws_xpixel);
484 put_value(proc, "ws_ypixel", "%u", ws->ws_ypixel);
486 return (verbose > 0) ? IF_ALL : 0;
488 case KIOCBELL:
489 if ((bell = (struct kio_bell *)ptr) == NULL)
490 return IF_OUT;
492 put_value(proc, "kb_pitch", "%u", bell->kb_pitch);
493 put_value(proc, "kb_volume", "%lu", bell->kb_volume);
494 put_struct_timeval(proc, "kb_duration", PF_LOCADDR,
495 (vir_bytes)&bell->kb_duration);
497 return IF_ALL;
499 case KIOCSLEDS:
500 if ((leds = (struct kio_leds *)ptr) == NULL)
501 return IF_OUT;
503 put_flags(proc, "kl_bits", kbd_leds, COUNT(kbd_leds), "0x%x",
504 leds->kl_bits);
505 return IF_ALL;
507 case PCI_IOC_CFGREAD:
508 if ((pci_cfgreg = (struct pciio_cfgreg *)ptr) == NULL)
509 return IF_IN;
511 put_ptr(proc, "reg", (vir_bytes)pci_cfgreg->reg);
512 put_value(proc, "val", "%08x", pci_cfgreg->val);
513 return IF_ALL;
515 case PCI_IOC_CFGWRITE:
516 if ((pci_cfgreg = (struct pciio_cfgreg *)ptr) == NULL)
517 return IF_OUT;
519 put_ptr(proc, "reg", (vir_bytes)pci_cfgreg->reg);
520 put_value(proc, "val", "%08x", pci_cfgreg->val);
521 return IF_ALL;
523 case PCI_IOC_BDF_CFGREAD:
524 if ((pci_bdf_cfgreg = (struct pciio_bdf_cfgreg *)ptr) == NULL)
525 return IF_IN;
527 put_value(proc, "bus", "%u", pci_bdf_cfgreg->bus);
528 put_value(proc, "device", "%u", pci_bdf_cfgreg->device);
529 put_value(proc, "function", "%u", pci_bdf_cfgreg->function);
530 put_ptr(proc, "cfgreg.reg", (vir_bytes)pci_bdf_cfgreg->cfgreg.reg);
531 put_value(proc, "cfgreg.val", "%08x", pci_bdf_cfgreg->cfgreg.val);
532 return IF_ALL;
534 case PCI_IOC_BDF_CFGWRITE:
535 if ((pci_bdf_cfgreg = (struct pciio_bdf_cfgreg *)ptr) == NULL)
536 return IF_OUT;
538 put_value(proc, "bus", "%u", pci_bdf_cfgreg->bus);
539 put_value(proc, "device", "%u", pci_bdf_cfgreg->device);
540 put_value(proc, "function", "%u", pci_bdf_cfgreg->function);
541 put_ptr(proc, "cfgreg.reg", (vir_bytes)pci_bdf_cfgreg->cfgreg.reg);
542 put_value(proc, "cfgreg.val", "%08x", pci_bdf_cfgreg->cfgreg.val);
543 return IF_ALL;
545 case PCI_IOC_BUSINFO:
546 if ((pci_businfo = (struct pciio_businfo *)ptr) == NULL)
547 return IF_IN;
549 put_value(proc, "busno", "%u", pci_businfo->busno);
550 put_value(proc, "maxdevs", "%u", pci_businfo->maxdevs);
551 return IF_ALL;
553 case PCI_IOC_MAP:
554 if ((pci_iomap = (struct pciio_map *)ptr) == NULL)
555 return IF_OUT|IF_IN;
557 put_value(proc, "flags", "%x", pci_iomap->flags);
558 put_value(proc, "phys_offset", "%08x", pci_iomap->phys_offset);
559 put_value(proc, "size", "%zu", pci_iomap->size);
560 put_value(proc, "readonly", "%x", pci_iomap->readonly);
562 if (IF_IN == dir)
563 put_ptr(proc, "vaddr_ret", (vir_bytes)pci_iomap->vaddr_ret);
565 return IF_ALL;
567 case PCI_IOC_UNMAP:
568 if ((pci_iomap = (struct pciio_map *)ptr) == NULL)
569 return IF_OUT;
571 put_ptr(proc, "vaddr", (vir_bytes)pci_iomap->vaddr);
573 return IF_ALL;
575 case PCI_IOC_RESERVE:
576 if ((pci_acl = (struct pciio_acl *)ptr) == NULL)
577 return IF_OUT;
579 put_value(proc, "domain", "%u", pci_acl->domain);
580 put_value(proc, "bus", "%u", pci_acl->bus);
581 put_value(proc, "device", "%u", pci_acl->device);
582 put_value(proc, "function", "%u", pci_acl->function);
584 return IF_ALL;
585 case PCI_IOC_RELEASE:
586 if ((pci_acl = (struct pciio_acl *)ptr) == NULL)
587 return IF_OUT;
589 put_value(proc, "domain", "%u", pci_acl->domain);
590 put_value(proc, "bus", "%u", pci_acl->bus);
591 put_value(proc, "device", "%u", pci_acl->device);
592 put_value(proc, "function", "%u", pci_acl->function);
594 return IF_ALL;
596 default:
597 return 0;