summaryrefslogtreecommitdiff
path: root/ptp.c
blob: 773f3d59a0005538ed7b201c859a0307e57d975f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "defs.h"
#include <sys/ioctl.h>
#include <linux/ptp_clock.h>

static const struct xlat ptp_flags_options[] = {
	XLAT(PTP_ENABLE_FEATURE),
	XLAT(PTP_RISING_EDGE),
	XLAT(PTP_FALLING_EDGE),
	XLAT_END
};


int ptp_ioctl(struct tcb *tcp, long code, long arg)
{
	if (!verbose(tcp))
		return 0;

	switch (code) {
		case PTP_CLOCK_GETCAPS: /* decode on exit */
		{
			struct ptp_clock_caps caps;

			if (entering(tcp) || syserror(tcp) ||
			    umove(tcp, arg, &caps) < 0)
				return 0;

			tprintf(", {max_adj=%d, n_alarm=%d, n_ext_ts=%d, n_per_out=%d, pps=%d}",
				caps.max_adj, caps.n_alarm, caps.n_ext_ts,
				caps.n_per_out, caps.pps);
			return 1;
		}

		case PTP_EXTTS_REQUEST: /* decode on enter */
		{
			struct ptp_extts_request extts;

			if (exiting(tcp))
				return 1;
			if (umove(tcp, arg, &extts) < 0) {
				tprintf(", %#lx", arg);
				return 0;
			}
			tprintf(", {index=%d, flags=", extts.index);
			printflags(ptp_flags_options, extts.flags, "PTP_???");
			tprints("}");
			return 1;
		}

		case PTP_PEROUT_REQUEST: /* decode on enter */
		{
			struct ptp_perout_request perout;

			if (exiting(tcp))
				return 1;
			if (umove(tcp, arg, &perout) < 0) {
				tprintf(", %#lx", arg);
				return 0;
			}

			tprintf(", {start={%" PRId64 ", %" PRIu32 "}"
				   ", period={%" PRId64 ", %" PRIu32 "}"
				   ", index=%d, flags=",
				(int64_t)perout.start.sec, perout.start.nsec,
				(int64_t)perout.period.sec, perout.period.nsec,
				perout.index);
			printflags(ptp_flags_options, perout.flags, "PTP_???");
			tprints("}");
			return 1;
		}

		case PTP_ENABLE_PPS: /* decode on enter */
			if (entering(tcp))
				tprintf(", %ld", arg);
			return 1;

		case PTP_SYS_OFFSET: /* decode on exit */
		{
			struct ptp_sys_offset sysoff;
			unsigned int i;

			if (entering(tcp) || umove(tcp, arg, &sysoff) < 0)
				return 0;

			tprintf(", {n_samples=%u, ts={", sysoff.n_samples);
			if (syserror(tcp)) {
				tprints("...}}");
				return 1;
			}
			if (sysoff.n_samples > PTP_MAX_SAMPLES)
				sysoff.n_samples = PTP_MAX_SAMPLES;
			tprintf("{%" PRId64 ", %" PRIu32 "}",
				(int64_t)sysoff.ts[0].sec, sysoff.ts[0].nsec);
			for (i = 1; i < 2*sysoff.n_samples+1; ++i)
				tprintf(", {%" PRId64 ", %" PRIu32 "}",
					(int64_t)sysoff.ts[i].sec, sysoff.ts[i].nsec);
			tprints("}}");
			return 1;
		}

		default: /* decode on exit */
			return 0;
	}
}