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