1#include "defs.h"
2#include <sys/ioctl.h>
3#include <linux/ptp_clock.h>
4
5#include "xlat/ptp_flags_options.h"
6
7int ptp_ioctl(struct tcb *tcp, long code, long arg)
8{
9	if (!verbose(tcp))
10		return 0;
11
12	switch (code) {
13		case PTP_CLOCK_GETCAPS: /* decode on exit */
14		{
15			struct ptp_clock_caps caps;
16
17			if (entering(tcp) || syserror(tcp) ||
18			    umove(tcp, arg, &caps) < 0)
19				return 0;
20
21			tprintf(", {max_adj=%d, n_alarm=%d, n_ext_ts=%d, n_per_out=%d, pps=%d}",
22				caps.max_adj, caps.n_alarm, caps.n_ext_ts,
23				caps.n_per_out, caps.pps);
24			return 1;
25		}
26
27		case PTP_EXTTS_REQUEST: /* decode on enter */
28		{
29			struct ptp_extts_request extts;
30
31			if (exiting(tcp))
32				return 1;
33			if (umove(tcp, arg, &extts) < 0) {
34				tprintf(", %#lx", arg);
35				return 0;
36			}
37			tprintf(", {index=%d, flags=", extts.index);
38			printflags(ptp_flags_options, extts.flags, "PTP_???");
39			tprints("}");
40			return 1;
41		}
42
43		case PTP_PEROUT_REQUEST: /* decode on enter */
44		{
45			struct ptp_perout_request perout;
46
47			if (exiting(tcp))
48				return 1;
49			if (umove(tcp, arg, &perout) < 0) {
50				tprintf(", %#lx", arg);
51				return 0;
52			}
53
54			tprintf(", {start={%" PRId64 ", %" PRIu32 "}"
55				   ", period={%" PRId64 ", %" PRIu32 "}"
56				   ", index=%d, flags=",
57				(int64_t)perout.start.sec, perout.start.nsec,
58				(int64_t)perout.period.sec, perout.period.nsec,
59				perout.index);
60			printflags(ptp_flags_options, perout.flags, "PTP_???");
61			tprints("}");
62			return 1;
63		}
64
65		case PTP_ENABLE_PPS: /* decode on enter */
66			if (entering(tcp))
67				tprintf(", %ld", arg);
68			return 1;
69
70		case PTP_SYS_OFFSET: /* decode on exit */
71		{
72			struct ptp_sys_offset sysoff;
73			unsigned int i;
74
75			if (entering(tcp) || umove(tcp, arg, &sysoff) < 0)
76				return 0;
77
78			tprintf(", {n_samples=%u, ts={", sysoff.n_samples);
79			if (syserror(tcp)) {
80				tprints("...}}");
81				return 1;
82			}
83			if (sysoff.n_samples > PTP_MAX_SAMPLES)
84				sysoff.n_samples = PTP_MAX_SAMPLES;
85			tprintf("{%" PRId64 ", %" PRIu32 "}",
86				(int64_t)sysoff.ts[0].sec, sysoff.ts[0].nsec);
87			for (i = 1; i < 2*sysoff.n_samples+1; ++i)
88				tprintf(", {%" PRId64 ", %" PRIu32 "}",
89					(int64_t)sysoff.ts[i].sec, sysoff.ts[i].nsec);
90			tprints("}}");
91			return 1;
92		}
93
94		default: /* decode on exit */
95			return 0;
96	}
97}
98