1*cdfa2a7eSchristos /* $NetBSD: timepps-SCO.h,v 1.5 2020/05/25 20:47:20 christos Exp $ */
2abb0f93cSkardel
3abb0f93cSkardel /***********************************************************************
4abb0f93cSkardel * *
5abb0f93cSkardel * Copyright (c) David L. Mills 1999-2000 *
6abb0f93cSkardel * *
7abb0f93cSkardel * Permission to use, copy, modify, and distribute this software and *
88585484eSchristos * its documentation for any purpose and with or without fee is hereby *
9abb0f93cSkardel * granted, provided that the above copyright notice appears in all *
10abb0f93cSkardel * copies and that both the copyright notice and this permission *
11abb0f93cSkardel * notice appear in supporting documentation, and that the name *
12abb0f93cSkardel * University of Delaware not be used in advertising or publicity *
13abb0f93cSkardel * pertaining to distribution of the software without specific, *
14abb0f93cSkardel * written prior permission. The University of Delaware makes no *
15abb0f93cSkardel * representations about the suitability this software for any *
16abb0f93cSkardel * purpose. It is provided "as is" without express or implied *
17abb0f93cSkardel * warranty. *
18abb0f93cSkardel * *
19abb0f93cSkardel ***********************************************************************
20abb0f93cSkardel * *
21abb0f93cSkardel * This header file complies with "Pulse-Per-Second API for UNIX-like *
22abb0f93cSkardel * Operating Systems, Version 1.0", rfc2783. Credit is due Jeff Mogul *
23abb0f93cSkardel * and Marc Brett, from whom much of this code was shamelessly stolen. *
24abb0f93cSkardel * *
25abb0f93cSkardel * this modified timepps.h can be used to provide a PPSAPI interface *
26abb0f93cSkardel * to a machine running SCO Unix. *
27abb0f93cSkardel * *
28abb0f93cSkardel ***********************************************************************
29abb0f93cSkardel * *
30abb0f93cSkardel * A full PPSAPI interface to the SCO Unix kernel would be better, but *
31abb0f93cSkardel * this at least removes the necessity for special coding from the NTP *
32abb0f93cSkardel * NTP drivers. *
33abb0f93cSkardel * *
34abb0f93cSkardel ***********************************************************************
35abb0f93cSkardel * *
36abb0f93cSkardel * Some of this include file *
37abb0f93cSkardel * Copyright (c) 1999 by Ulrich Windl, *
38abb0f93cSkardel * based on code by Reg Clemens <reg@dwf.com> *
39abb0f93cSkardel * based on code by Poul-Henning Kamp <phk@FreeBSD.org> *
40abb0f93cSkardel * *
41abb0f93cSkardel ***********************************************************************
42abb0f93cSkardel * *
43abb0f93cSkardel * "THE BEER-WARE LICENSE" (Revision 42): *
44abb0f93cSkardel * <phk@FreeBSD.org> wrote this file. As long as you retain this *
45abb0f93cSkardel * notice you can do whatever you want with this stuff. If we meet some*
46abb0f93cSkardel * day, and you think this stuff is worth it, you can buy me a beer *
47abb0f93cSkardel * in return. Poul-Henning Kamp *
48abb0f93cSkardel * *
49abb0f93cSkardel **********************************************************************/
50abb0f93cSkardel
51abb0f93cSkardel /*SCO UNIX version, TIOCDCDTIMESTAMP assumed to exist. */
52abb0f93cSkardel
53abb0f93cSkardel #ifndef _SYS_TIMEPPS_H_
54abb0f93cSkardel #define _SYS_TIMEPPS_H_
55abb0f93cSkardel
56abb0f93cSkardel #include <termios.h> /* to get TIOCDCDTIMESTAMP */
57abb0f93cSkardel
58abb0f93cSkardel /* Implementation note: the logical states ``assert'' and ``clear''
59abb0f93cSkardel * are implemented in terms of the UART register, i.e. ``assert''
60abb0f93cSkardel * means the bit is set.
61abb0f93cSkardel */
62abb0f93cSkardel
63abb0f93cSkardel /*
64abb0f93cSkardel * The following definitions are architecture independent
65abb0f93cSkardel */
66abb0f93cSkardel
67abb0f93cSkardel #define PPS_API_VERS_1 1 /* API version number */
68abb0f93cSkardel #define PPS_JAN_1970 2208988800UL /* 1970 - 1900 in seconds */
69abb0f93cSkardel #define PPS_NANOSECOND 1000000000L /* one nanosecond in decimal */
70abb0f93cSkardel #define PPS_FRAC 4294967296. /* 2^32 as a double */
71abb0f93cSkardel
72abb0f93cSkardel #define PPS_NORMALIZE(x) /* normalize timespec */ \
73abb0f93cSkardel do { \
74abb0f93cSkardel if ((x).tv_nsec >= PPS_NANOSECOND) { \
75abb0f93cSkardel (x).tv_nsec -= PPS_NANOSECOND; \
76abb0f93cSkardel (x).tv_sec++; \
77abb0f93cSkardel } else if ((x).tv_nsec < 0) { \
78abb0f93cSkardel (x).tv_nsec += PPS_NANOSECOND; \
79abb0f93cSkardel (x).tv_sec--; \
80abb0f93cSkardel } \
81abb0f93cSkardel } while (0)
82abb0f93cSkardel
83abb0f93cSkardel #define PPS_TSPECTONTP(x) /* convert timespec to l_fp */ \
84abb0f93cSkardel do { \
85abb0f93cSkardel double d_temp; \
86abb0f93cSkardel \
87abb0f93cSkardel (x).integral += (unsigned int)PPS_JAN_1970; \
88abb0f93cSkardel d_temp = (x).fractional * PPS_FRAC / PPS_NANOSECOND; \
89abb0f93cSkardel if (d_temp >= PPS_FRAC) \
90abb0f93cSkardel (x).integral++; \
91abb0f93cSkardel (x).fractional = (unsigned int)d_temp; \
92abb0f93cSkardel } while (0)
93abb0f93cSkardel
94abb0f93cSkardel /*
95abb0f93cSkardel * Device/implementation parameters (mode)
96abb0f93cSkardel */
97abb0f93cSkardel
98abb0f93cSkardel #define PPS_CAPTUREASSERT 0x01 /* capture assert events */
99abb0f93cSkardel #define PPS_CAPTURECLEAR 0x02 /* capture clear events */
100abb0f93cSkardel #define PPS_CAPTUREBOTH 0x03 /* capture assert and clear events */
101abb0f93cSkardel
102abb0f93cSkardel #define PPS_OFFSETASSERT 0x10 /* apply compensation for assert ev. */
103abb0f93cSkardel #define PPS_OFFSETCLEAR 0x20 /* apply compensation for clear ev. */
104abb0f93cSkardel #define PPS_OFFSETBOTH 0x30 /* apply compensation for both */
105abb0f93cSkardel
106abb0f93cSkardel #define PPS_CANWAIT 0x100 /* Can we wait for an event? */
107abb0f93cSkardel #define PPS_CANPOLL 0x200 /* "This bit is reserved for */
108abb0f93cSkardel
109abb0f93cSkardel /*
110abb0f93cSkardel * Kernel actions (mode)
111abb0f93cSkardel */
112abb0f93cSkardel
113abb0f93cSkardel #define PPS_ECHOASSERT 0x40 /* feed back assert event to output */
114abb0f93cSkardel #define PPS_ECHOCLEAR 0x80 /* feed back clear event to output */
115abb0f93cSkardel
116abb0f93cSkardel /*
117abb0f93cSkardel * Timestamp formats (tsformat)
118abb0f93cSkardel */
119abb0f93cSkardel
120abb0f93cSkardel #define PPS_TSFMT_TSPEC 0x1000 /* select timespec format */
121abb0f93cSkardel #define PPS_TSFMT_NTPFP 0x2000 /* select NTP format */
122abb0f93cSkardel
123abb0f93cSkardel /*
124abb0f93cSkardel * Kernel discipline actions (not used in Solaris)
125abb0f93cSkardel */
126abb0f93cSkardel
127abb0f93cSkardel #define PPS_KC_HARDPPS 0 /* enable kernel consumer */
128abb0f93cSkardel #define PPS_KC_HARDPPS_PLL 1 /* phase-lock mode */
129abb0f93cSkardel #define PPS_KC_HARDPPS_FLL 2 /* frequency-lock mode */
130abb0f93cSkardel
131abb0f93cSkardel /*
132abb0f93cSkardel * Type definitions
133abb0f93cSkardel */
134abb0f93cSkardel
135abb0f93cSkardel typedef unsigned long pps_seq_t; /* sequence number */
136abb0f93cSkardel
137abb0f93cSkardel typedef struct ntp_fp {
138abb0f93cSkardel unsigned int integral;
139abb0f93cSkardel unsigned int fractional;
140abb0f93cSkardel } ntp_fp_t; /* NTP-compatible time stamp */
141abb0f93cSkardel
142abb0f93cSkardel typedef union pps_timeu { /* timestamp format */
143abb0f93cSkardel struct timespec tspec;
144abb0f93cSkardel ntp_fp_t ntpfp;
145abb0f93cSkardel unsigned long longpad[3];
146abb0f93cSkardel } pps_timeu_t; /* generic data type to represent time stamps */
147abb0f93cSkardel
148abb0f93cSkardel /*
149abb0f93cSkardel * Timestamp information structure
150abb0f93cSkardel */
151abb0f93cSkardel
152abb0f93cSkardel typedef struct pps_info {
153abb0f93cSkardel pps_seq_t assert_sequence; /* seq. num. of assert event */
154abb0f93cSkardel pps_seq_t clear_sequence; /* seq. num. of clear event */
155abb0f93cSkardel pps_timeu_t assert_tu; /* time of assert event */
156abb0f93cSkardel pps_timeu_t clear_tu; /* time of clear event */
157abb0f93cSkardel int current_mode; /* current mode bits */
158abb0f93cSkardel } pps_info_t;
159abb0f93cSkardel
160abb0f93cSkardel #define assert_timestamp assert_tu.tspec
161abb0f93cSkardel #define clear_timestamp clear_tu.tspec
162abb0f93cSkardel
163abb0f93cSkardel #define assert_timestamp_ntpfp assert_tu.ntpfp
164abb0f93cSkardel #define clear_timestamp_ntpfp clear_tu.ntpfp
165abb0f93cSkardel
166abb0f93cSkardel /*
167abb0f93cSkardel * Parameter structure
168abb0f93cSkardel */
169abb0f93cSkardel
170abb0f93cSkardel typedef struct pps_params {
171abb0f93cSkardel int api_version; /* API version # */
172abb0f93cSkardel int mode; /* mode bits */
173abb0f93cSkardel pps_timeu_t assert_off_tu; /* offset compensation for assert */
174abb0f93cSkardel pps_timeu_t clear_off_tu; /* offset compensation for clear */
175abb0f93cSkardel } pps_params_t;
176abb0f93cSkardel
177abb0f93cSkardel #define assert_offset assert_off_tu.tspec
178abb0f93cSkardel #define clear_offset clear_off_tu.tspec
179abb0f93cSkardel
180abb0f93cSkardel #define assert_offset_ntpfp assert_off_tu.ntpfp
181abb0f93cSkardel #define clear_offset_ntpfp clear_off_tu.ntpfp
182abb0f93cSkardel
183abb0f93cSkardel /*
184abb0f93cSkardel * The following definitions are architecture-dependent
185abb0f93cSkardel */
186abb0f93cSkardel
187abb0f93cSkardel #define PPS_CAP (PPS_CAPTUREASSERT | PPS_OFFSETASSERT | PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)
188abb0f93cSkardel #define PPS_RO (PPS_CANWAIT | PPS_CANPOLL | PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)
189abb0f93cSkardel
190abb0f93cSkardel typedef struct {
191abb0f93cSkardel int filedes; /* file descriptor */
192abb0f93cSkardel pps_params_t params; /* PPS parameters set by user */
193abb0f93cSkardel struct timeval tv_save;
194abb0f93cSkardel pps_seq_t serial;
195abb0f93cSkardel } pps_unit_t;
196abb0f93cSkardel
197abb0f93cSkardel typedef pps_unit_t* pps_handle_t; /* pps handlebars */
198abb0f93cSkardel
199abb0f93cSkardel /*
200abb0f93cSkardel *------ Here begins the implementation-specific part! ------
201abb0f93cSkardel */
202abb0f93cSkardel
203abb0f93cSkardel #include <errno.h>
204abb0f93cSkardel
205abb0f93cSkardel /*
206abb0f93cSkardel * create PPS handle from file descriptor
207abb0f93cSkardel */
208abb0f93cSkardel
209abb0f93cSkardel static inline int
time_pps_create(int filedes,pps_handle_t * handle)210abb0f93cSkardel time_pps_create(
211abb0f93cSkardel int filedes, /* file descriptor */
212abb0f93cSkardel pps_handle_t *handle /* returned handle */
213abb0f93cSkardel )
214abb0f93cSkardel {
215abb0f93cSkardel int one = 1;
216abb0f93cSkardel
217abb0f93cSkardel /*
218abb0f93cSkardel * Check for valid arguments and attach PPS signal.
219abb0f93cSkardel */
220abb0f93cSkardel
221abb0f93cSkardel if (!handle) {
222abb0f93cSkardel errno = EFAULT;
223abb0f93cSkardel return (-1); /* null pointer */
224abb0f93cSkardel }
225abb0f93cSkardel
226abb0f93cSkardel /*
227abb0f93cSkardel * Allocate and initialize default unit structure.
228abb0f93cSkardel */
229abb0f93cSkardel
230abb0f93cSkardel *handle = malloc(sizeof(pps_unit_t));
231abb0f93cSkardel if (!(*handle)) {
232abb0f93cSkardel errno = EBADF;
233abb0f93cSkardel return (-1); /* what, no memory? */
234abb0f93cSkardel }
235abb0f93cSkardel
236abb0f93cSkardel memset(*handle, 0, sizeof(pps_unit_t));
237abb0f93cSkardel (*handle)->filedes = filedes;
238abb0f93cSkardel (*handle)->params.api_version = PPS_API_VERS_1;
239abb0f93cSkardel (*handle)->params.mode = PPS_CAPTUREASSERT | PPS_TSFMT_TSPEC;
240abb0f93cSkardel return (0);
241abb0f93cSkardel }
242abb0f93cSkardel
243abb0f93cSkardel /*
244abb0f93cSkardel * release PPS handle
245abb0f93cSkardel */
246abb0f93cSkardel
247abb0f93cSkardel static inline int
time_pps_destroy(pps_handle_t handle)248abb0f93cSkardel time_pps_destroy(
249abb0f93cSkardel pps_handle_t handle
250abb0f93cSkardel )
251abb0f93cSkardel {
252abb0f93cSkardel /*
253abb0f93cSkardel * Check for valid arguments and detach PPS signal.
254abb0f93cSkardel */
255abb0f93cSkardel
256abb0f93cSkardel if (!handle) {
257abb0f93cSkardel errno = EBADF;
258abb0f93cSkardel return (-1); /* bad handle */
259abb0f93cSkardel }
260abb0f93cSkardel free(handle);
261abb0f93cSkardel return (0);
262abb0f93cSkardel }
263abb0f93cSkardel
264abb0f93cSkardel /*
265abb0f93cSkardel * set parameters for handle
266abb0f93cSkardel */
267abb0f93cSkardel
268abb0f93cSkardel static inline int
time_pps_setparams(pps_handle_t handle,const pps_params_t * params)269abb0f93cSkardel time_pps_setparams(
270abb0f93cSkardel pps_handle_t handle,
271abb0f93cSkardel const pps_params_t *params
272abb0f93cSkardel )
273abb0f93cSkardel {
274abb0f93cSkardel int mode, mode_in;
275abb0f93cSkardel /*
276abb0f93cSkardel * Check for valid arguments and set parameters.
277abb0f93cSkardel */
278abb0f93cSkardel
279abb0f93cSkardel if (!handle) {
280abb0f93cSkardel errno = EBADF;
281abb0f93cSkardel return (-1); /* bad handle */
282abb0f93cSkardel }
283abb0f93cSkardel
284abb0f93cSkardel if (!params) {
285abb0f93cSkardel errno = EFAULT;
286abb0f93cSkardel return (-1); /* bad argument */
287abb0f93cSkardel }
288abb0f93cSkardel
289abb0f93cSkardel /*
290abb0f93cSkardel * There was no reasonable consensu in the API working group.
291abb0f93cSkardel * I require `api_version' to be set!
292abb0f93cSkardel */
293abb0f93cSkardel
294abb0f93cSkardel if (params->api_version != PPS_API_VERS_1) {
295abb0f93cSkardel errno = EINVAL;
296abb0f93cSkardel return(-1);
297abb0f93cSkardel }
298abb0f93cSkardel
299abb0f93cSkardel /*
300abb0f93cSkardel * only settable modes are PPS_CAPTUREASSERT and PPS_OFFSETASSERT
301abb0f93cSkardel */
302abb0f93cSkardel
303abb0f93cSkardel mode_in = params->mode;
304abb0f93cSkardel
305abb0f93cSkardel /* turn off read-only bits */
306abb0f93cSkardel
307abb0f93cSkardel mode_in &= ~PPS_RO;
308abb0f93cSkardel
309abb0f93cSkardel /* test remaining bits, should only have captureassert and/or offsetassert */
310abb0f93cSkardel
311abb0f93cSkardel if (mode_in & ~(PPS_CAPTUREASSERT | PPS_OFFSETASSERT)) {
312abb0f93cSkardel errno = EOPNOTSUPP;
313abb0f93cSkardel return(-1);
314abb0f93cSkardel }
315abb0f93cSkardel
316abb0f93cSkardel /*
317abb0f93cSkardel * ok, ready to go.
318abb0f93cSkardel */
319abb0f93cSkardel
320abb0f93cSkardel mode = handle->params.mode;
321abb0f93cSkardel memcpy(&handle->params, params, sizeof(pps_params_t));
322abb0f93cSkardel handle->params.api_version = PPS_API_VERS_1;
323abb0f93cSkardel handle->params.mode = mode | mode_in;
324abb0f93cSkardel return (0);
325abb0f93cSkardel }
326abb0f93cSkardel
327abb0f93cSkardel /*
328abb0f93cSkardel * get parameters for handle
329abb0f93cSkardel */
330abb0f93cSkardel
331abb0f93cSkardel static inline int
time_pps_getparams(pps_handle_t handle,pps_params_t * params)332abb0f93cSkardel time_pps_getparams(
333abb0f93cSkardel pps_handle_t handle,
334abb0f93cSkardel pps_params_t *params
335abb0f93cSkardel )
336abb0f93cSkardel {
337abb0f93cSkardel /*
338abb0f93cSkardel * Check for valid arguments and get parameters.
339abb0f93cSkardel */
340abb0f93cSkardel
341abb0f93cSkardel if (!handle) {
342abb0f93cSkardel errno = EBADF;
343abb0f93cSkardel return (-1); /* bad handle */
344abb0f93cSkardel }
345abb0f93cSkardel
346abb0f93cSkardel if (!params) {
347abb0f93cSkardel errno = EFAULT;
348abb0f93cSkardel return (-1); /* bad argument */
349abb0f93cSkardel }
350abb0f93cSkardel
351abb0f93cSkardel memcpy(params, &handle->params, sizeof(pps_params_t));
352abb0f93cSkardel return (0);
353abb0f93cSkardel }
354abb0f93cSkardel
355abb0f93cSkardel /* (
356abb0f93cSkardel * get capabilities for handle
357abb0f93cSkardel */
358abb0f93cSkardel
359abb0f93cSkardel static inline int
time_pps_getcap(pps_handle_t handle,int * mode)360abb0f93cSkardel time_pps_getcap(
361abb0f93cSkardel pps_handle_t handle,
362abb0f93cSkardel int *mode
363abb0f93cSkardel )
364abb0f93cSkardel {
365abb0f93cSkardel /*
366abb0f93cSkardel * Check for valid arguments and get capabilities.
367abb0f93cSkardel */
368abb0f93cSkardel
369abb0f93cSkardel if (!handle) {
370abb0f93cSkardel errno = EBADF;
371abb0f93cSkardel return (-1); /* bad handle */
372abb0f93cSkardel }
373abb0f93cSkardel
374abb0f93cSkardel if (!mode) {
375abb0f93cSkardel errno = EFAULT;
376abb0f93cSkardel return (-1); /* bad argument */
377abb0f93cSkardel }
378abb0f93cSkardel *mode = PPS_CAP;
379abb0f93cSkardel return (0);
380abb0f93cSkardel }
381abb0f93cSkardel
382abb0f93cSkardel /*
383abb0f93cSkardel * Fetch timestamps
384abb0f93cSkardel */
385abb0f93cSkardel
386abb0f93cSkardel static inline int
time_pps_fetch(pps_handle_t handle,const int tsformat,pps_info_t * ppsinfo,const struct timespec * timeout)387abb0f93cSkardel time_pps_fetch(
388abb0f93cSkardel pps_handle_t handle,
389abb0f93cSkardel const int tsformat,
390abb0f93cSkardel pps_info_t *ppsinfo,
391abb0f93cSkardel const struct timespec *timeout
392abb0f93cSkardel )
393abb0f93cSkardel {
394abb0f93cSkardel struct timeval tv;
395abb0f93cSkardel pps_info_t infobuf;
396abb0f93cSkardel
397abb0f93cSkardel /*
398abb0f93cSkardel * Check for valid arguments and fetch timestamps
399abb0f93cSkardel */
400abb0f93cSkardel
401abb0f93cSkardel if (!handle) {
402abb0f93cSkardel errno = EBADF;
403abb0f93cSkardel return (-1); /* bad handle */
404abb0f93cSkardel }
405abb0f93cSkardel
406abb0f93cSkardel if (!ppsinfo) {
407abb0f93cSkardel errno = EFAULT;
408abb0f93cSkardel return (-1); /* bad argument */
409abb0f93cSkardel }
410abb0f93cSkardel
411abb0f93cSkardel /*
412abb0f93cSkardel * nb. PPS_CANWAIT is NOT set by the implementation, we can totally
413abb0f93cSkardel * ignore the timeout variable.
414abb0f93cSkardel */
415abb0f93cSkardel
416abb0f93cSkardel memset(&infobuf, 0, sizeof(infobuf));
417abb0f93cSkardel
418abb0f93cSkardel /*
419abb0f93cSkardel * if not captureassert, nothing to return.
420abb0f93cSkardel */
421abb0f93cSkardel
422abb0f93cSkardel if (!handle->params.mode & PPS_CAPTUREASSERT) {
423abb0f93cSkardel memcpy(ppsinfo, &infobuf, sizeof(pps_info_t));
424abb0f93cSkardel return (0);
425abb0f93cSkardel }
426abb0f93cSkardel
427abb0f93cSkardel if (ioctl(instance->filedes, TIOCDCDTIMESTAMP, &tv) < 0) {
428abb0f93cSkardel perror("time_pps_fetch:");
429abb0f93cSkardel errno = EOPNOTSUPP;
430abb0f93cSkardel return(-1);
431abb0f93cSkardel }
432abb0f93cSkardel
433abb0f93cSkardel /*
434abb0f93cSkardel * fake serial here
435abb0f93cSkardel */
436abb0f93cSkardel
437abb0f93cSkardel if (tv.tv_sec != handle->tv_save.tv_sec || tv.tv_usec != handle->tv_save.tv_usec) {
438abb0f93cSkardel handle->tv_save = tv;
439abb0f93cSkardel handle->serial++;
440abb0f93cSkardel }
441abb0f93cSkardel
442abb0f93cSkardel /*
443abb0f93cSkardel * Apply offsets as specified. Note that only assert timestamps
444abb0f93cSkardel * are captured by this interface.
445abb0f93cSkardel */
446abb0f93cSkardel
447abb0f93cSkardel infobuf.assert_sequence = handle->serial;
448abb0f93cSkardel infobuf.assert_timestamp.tv_sec = tv.tv_sec;
449abb0f93cSkardel infobuf.assert_timestamp.tv_nsec = tv.tv_usec * 1000;
450abb0f93cSkardel
451abb0f93cSkardel if (handle->params.mode & PPS_OFFSETASSERT) {
452abb0f93cSkardel infobuf.assert_timestamp.tv_sec += handle->params.assert_offset.tv_sec;
453abb0f93cSkardel infobuf.assert_timestamp.tv_nsec += handle->params.assert_offset.tv_nsec;
454abb0f93cSkardel PPS_NORMALIZE(infobuf.assert_timestamp);
455abb0f93cSkardel }
456abb0f93cSkardel
457abb0f93cSkardel /*
458abb0f93cSkardel * Translate to specified format
459abb0f93cSkardel */
460abb0f93cSkardel
461abb0f93cSkardel switch (tsformat) {
462abb0f93cSkardel case PPS_TSFMT_TSPEC:
463abb0f93cSkardel break; /* timespec format requires no translation */
464abb0f93cSkardel
465abb0f93cSkardel case PPS_TSFMT_NTPFP: /* NTP format requires conversion to fraction form */
466abb0f93cSkardel PPS_TSPECTONTP(infobuf.assert_timestamp_ntpfp);
467abb0f93cSkardel break;
468abb0f93cSkardel
469abb0f93cSkardel default:
470abb0f93cSkardel errno = EINVAL;
471abb0f93cSkardel return (-1);
472abb0f93cSkardel }
473abb0f93cSkardel
474abb0f93cSkardel infobuf.current_mode = handle->params.mode;
475abb0f93cSkardel memcpy(ppsinfo, &infobuf, sizeof(pps_info_t));
476abb0f93cSkardel return (0);
477abb0f93cSkardel }
478abb0f93cSkardel
479abb0f93cSkardel /*
480abb0f93cSkardel * specify kernel consumer
481abb0f93cSkardel */
482abb0f93cSkardel
483abb0f93cSkardel static inline int
time_pps_kcbind(pps_handle_t handle,const int kernel_consumer,const int edge,const int tsformat)484abb0f93cSkardel time_pps_kcbind(
485abb0f93cSkardel pps_handle_t handle,
486abb0f93cSkardel const int kernel_consumer,
487abb0f93cSkardel const int edge, const int tsformat
488abb0f93cSkardel )
489abb0f93cSkardel {
490abb0f93cSkardel /*
491abb0f93cSkardel * Check for valid arguments and bind kernel consumer
492abb0f93cSkardel */
493abb0f93cSkardel if (!handle) {
494abb0f93cSkardel errno = EBADF;
495abb0f93cSkardel return (-1); /* bad handle */
496abb0f93cSkardel }
497abb0f93cSkardel if (geteuid() != 0) {
498abb0f93cSkardel errno = EPERM;
499abb0f93cSkardel return (-1); /* must be superuser */
500abb0f93cSkardel }
501abb0f93cSkardel errno = EOPNOTSUPP;
502abb0f93cSkardel return(-1);
503abb0f93cSkardel }
504abb0f93cSkardel
505abb0f93cSkardel #endif /* _SYS_TIMEPPS_H_ */
506