1de52133f1892ed2c385655473df90f3d2797fff9John Stultz/* valid adjtimex test
2de52133f1892ed2c385655473df90f3d2797fff9John Stultz *              by: John Stultz <john.stultz@linaro.org>
3de52133f1892ed2c385655473df90f3d2797fff9John Stultz *              (C) Copyright Linaro 2015
4de52133f1892ed2c385655473df90f3d2797fff9John Stultz *              Licensed under the GPLv2
5de52133f1892ed2c385655473df90f3d2797fff9John Stultz *
6de52133f1892ed2c385655473df90f3d2797fff9John Stultz *  This test validates adjtimex interface with valid
7de52133f1892ed2c385655473df90f3d2797fff9John Stultz *  and invalid test data.
8de52133f1892ed2c385655473df90f3d2797fff9John Stultz *
9de52133f1892ed2c385655473df90f3d2797fff9John Stultz *  Usage: valid-adjtimex
10de52133f1892ed2c385655473df90f3d2797fff9John Stultz *
11de52133f1892ed2c385655473df90f3d2797fff9John Stultz *  To build:
12de52133f1892ed2c385655473df90f3d2797fff9John Stultz *	$ gcc valid-adjtimex.c -o valid-adjtimex -lrt
13de52133f1892ed2c385655473df90f3d2797fff9John Stultz *
14de52133f1892ed2c385655473df90f3d2797fff9John Stultz *   This program is free software: you can redistribute it and/or modify
15de52133f1892ed2c385655473df90f3d2797fff9John Stultz *   it under the terms of the GNU General Public License as published by
16de52133f1892ed2c385655473df90f3d2797fff9John Stultz *   the Free Software Foundation, either version 2 of the License, or
17de52133f1892ed2c385655473df90f3d2797fff9John Stultz *   (at your option) any later version.
18de52133f1892ed2c385655473df90f3d2797fff9John Stultz *
19de52133f1892ed2c385655473df90f3d2797fff9John Stultz *   This program is distributed in the hope that it will be useful,
20de52133f1892ed2c385655473df90f3d2797fff9John Stultz *   but WITHOUT ANY WARRANTY; without even the implied warranty of
21de52133f1892ed2c385655473df90f3d2797fff9John Stultz *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22de52133f1892ed2c385655473df90f3d2797fff9John Stultz *   GNU General Public License for more details.
23de52133f1892ed2c385655473df90f3d2797fff9John Stultz */
24de52133f1892ed2c385655473df90f3d2797fff9John Stultz
25de52133f1892ed2c385655473df90f3d2797fff9John Stultz
26de52133f1892ed2c385655473df90f3d2797fff9John Stultz
27de52133f1892ed2c385655473df90f3d2797fff9John Stultz#include <stdio.h>
28de52133f1892ed2c385655473df90f3d2797fff9John Stultz#include <stdlib.h>
29de52133f1892ed2c385655473df90f3d2797fff9John Stultz#include <time.h>
30de52133f1892ed2c385655473df90f3d2797fff9John Stultz#include <sys/time.h>
31de52133f1892ed2c385655473df90f3d2797fff9John Stultz#include <sys/timex.h>
32de52133f1892ed2c385655473df90f3d2797fff9John Stultz#include <string.h>
33de52133f1892ed2c385655473df90f3d2797fff9John Stultz#include <signal.h>
34de52133f1892ed2c385655473df90f3d2797fff9John Stultz#include <unistd.h>
35de52133f1892ed2c385655473df90f3d2797fff9John Stultz#ifdef KTEST
36de52133f1892ed2c385655473df90f3d2797fff9John Stultz#include "../kselftest.h"
37de52133f1892ed2c385655473df90f3d2797fff9John Stultz#else
38de52133f1892ed2c385655473df90f3d2797fff9John Stultzstatic inline int ksft_exit_pass(void)
39de52133f1892ed2c385655473df90f3d2797fff9John Stultz{
40de52133f1892ed2c385655473df90f3d2797fff9John Stultz	exit(0);
41de52133f1892ed2c385655473df90f3d2797fff9John Stultz}
42de52133f1892ed2c385655473df90f3d2797fff9John Stultzstatic inline int ksft_exit_fail(void)
43de52133f1892ed2c385655473df90f3d2797fff9John Stultz{
44de52133f1892ed2c385655473df90f3d2797fff9John Stultz	exit(1);
45de52133f1892ed2c385655473df90f3d2797fff9John Stultz}
46de52133f1892ed2c385655473df90f3d2797fff9John Stultz#endif
47de52133f1892ed2c385655473df90f3d2797fff9John Stultz
48e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz#define NSEC_PER_SEC 1000000000LL
49e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz#define USEC_PER_SEC 1000000LL
50e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
51e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz#define ADJ_SETOFFSET 0x0100
52e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
53cd038753c3543ee6919469a4472cdf86ea0121c8Tri Vo#ifndef __ANDROID__
54e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz#include <sys/syscall.h>
55e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultzstatic int clock_adjtime(clockid_t id, struct timex *tx)
56e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz{
57cd038753c3543ee6919469a4472cdf86ea0121c8Tri Vo    return syscall(__NR_clock_adjtime, id, tx);
58e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz}
59cd038753c3543ee6919469a4472cdf86ea0121c8Tri Vo#endif
60de52133f1892ed2c385655473df90f3d2797fff9John Stultz
61de52133f1892ed2c385655473df90f3d2797fff9John Stultz/* clear NTP time_status & time_state */
62de52133f1892ed2c385655473df90f3d2797fff9John Stultzint clear_time_state(void)
63de52133f1892ed2c385655473df90f3d2797fff9John Stultz{
64de52133f1892ed2c385655473df90f3d2797fff9John Stultz	struct timex tx;
65de52133f1892ed2c385655473df90f3d2797fff9John Stultz	int ret;
66de52133f1892ed2c385655473df90f3d2797fff9John Stultz
67de52133f1892ed2c385655473df90f3d2797fff9John Stultz	tx.modes = ADJ_STATUS;
68de52133f1892ed2c385655473df90f3d2797fff9John Stultz	tx.status = 0;
69de52133f1892ed2c385655473df90f3d2797fff9John Stultz	ret = adjtimex(&tx);
70de52133f1892ed2c385655473df90f3d2797fff9John Stultz	return ret;
71de52133f1892ed2c385655473df90f3d2797fff9John Stultz}
72de52133f1892ed2c385655473df90f3d2797fff9John Stultz
73de52133f1892ed2c385655473df90f3d2797fff9John Stultz#define NUM_FREQ_VALID 32
74de52133f1892ed2c385655473df90f3d2797fff9John Stultz#define NUM_FREQ_OUTOFRANGE 4
75de52133f1892ed2c385655473df90f3d2797fff9John Stultz#define NUM_FREQ_INVALID 2
76de52133f1892ed2c385655473df90f3d2797fff9John Stultz
77de52133f1892ed2c385655473df90f3d2797fff9John Stultzlong valid_freq[NUM_FREQ_VALID] = {
78de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-499<<16,
79de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-450<<16,
80de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-400<<16,
81de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-350<<16,
82de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-300<<16,
83de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-250<<16,
84de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-200<<16,
85de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-150<<16,
86de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-100<<16,
87de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-75<<16,
88de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-50<<16,
89de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-25<<16,
90de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-10<<16,
91de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-5<<16,
92de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-1<<16,
93de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-1000,
94de52133f1892ed2c385655473df90f3d2797fff9John Stultz	1<<16,
95de52133f1892ed2c385655473df90f3d2797fff9John Stultz	5<<16,
96de52133f1892ed2c385655473df90f3d2797fff9John Stultz	10<<16,
97de52133f1892ed2c385655473df90f3d2797fff9John Stultz	25<<16,
98de52133f1892ed2c385655473df90f3d2797fff9John Stultz	50<<16,
99de52133f1892ed2c385655473df90f3d2797fff9John Stultz	75<<16,
100de52133f1892ed2c385655473df90f3d2797fff9John Stultz	100<<16,
101de52133f1892ed2c385655473df90f3d2797fff9John Stultz	150<<16,
102de52133f1892ed2c385655473df90f3d2797fff9John Stultz	200<<16,
103de52133f1892ed2c385655473df90f3d2797fff9John Stultz	250<<16,
104de52133f1892ed2c385655473df90f3d2797fff9John Stultz	300<<16,
105de52133f1892ed2c385655473df90f3d2797fff9John Stultz	350<<16,
106de52133f1892ed2c385655473df90f3d2797fff9John Stultz	400<<16,
107de52133f1892ed2c385655473df90f3d2797fff9John Stultz	450<<16,
108de52133f1892ed2c385655473df90f3d2797fff9John Stultz	499<<16,
109de52133f1892ed2c385655473df90f3d2797fff9John Stultz};
110de52133f1892ed2c385655473df90f3d2797fff9John Stultz
111de52133f1892ed2c385655473df90f3d2797fff9John Stultzlong outofrange_freq[NUM_FREQ_OUTOFRANGE] = {
112de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-1000<<16,
113de52133f1892ed2c385655473df90f3d2797fff9John Stultz	-550<<16,
114de52133f1892ed2c385655473df90f3d2797fff9John Stultz	550<<16,
115de52133f1892ed2c385655473df90f3d2797fff9John Stultz	1000<<16,
116de52133f1892ed2c385655473df90f3d2797fff9John Stultz};
117de52133f1892ed2c385655473df90f3d2797fff9John Stultz
118de52133f1892ed2c385655473df90f3d2797fff9John Stultz#define LONG_MAX (~0UL>>1)
119de52133f1892ed2c385655473df90f3d2797fff9John Stultz#define LONG_MIN (-LONG_MAX - 1)
120de52133f1892ed2c385655473df90f3d2797fff9John Stultz
121de52133f1892ed2c385655473df90f3d2797fff9John Stultzlong invalid_freq[NUM_FREQ_INVALID] = {
122de52133f1892ed2c385655473df90f3d2797fff9John Stultz	LONG_MAX,
123de52133f1892ed2c385655473df90f3d2797fff9John Stultz	LONG_MIN,
124de52133f1892ed2c385655473df90f3d2797fff9John Stultz};
125de52133f1892ed2c385655473df90f3d2797fff9John Stultz
126de52133f1892ed2c385655473df90f3d2797fff9John Stultzint validate_freq(void)
127de52133f1892ed2c385655473df90f3d2797fff9John Stultz{
128de52133f1892ed2c385655473df90f3d2797fff9John Stultz	struct timex tx;
129de52133f1892ed2c385655473df90f3d2797fff9John Stultz	int ret, pass = 0;
130de52133f1892ed2c385655473df90f3d2797fff9John Stultz	int i;
131de52133f1892ed2c385655473df90f3d2797fff9John Stultz
132de52133f1892ed2c385655473df90f3d2797fff9John Stultz	clear_time_state();
133de52133f1892ed2c385655473df90f3d2797fff9John Stultz
134de52133f1892ed2c385655473df90f3d2797fff9John Stultz	memset(&tx, 0, sizeof(struct timex));
135de52133f1892ed2c385655473df90f3d2797fff9John Stultz	/* Set the leap second insert flag */
136de52133f1892ed2c385655473df90f3d2797fff9John Stultz
137de52133f1892ed2c385655473df90f3d2797fff9John Stultz	printf("Testing ADJ_FREQ... ");
138de52133f1892ed2c385655473df90f3d2797fff9John Stultz	for (i = 0; i < NUM_FREQ_VALID; i++) {
139de52133f1892ed2c385655473df90f3d2797fff9John Stultz		tx.modes = ADJ_FREQUENCY;
140de52133f1892ed2c385655473df90f3d2797fff9John Stultz		tx.freq = valid_freq[i];
141de52133f1892ed2c385655473df90f3d2797fff9John Stultz
142de52133f1892ed2c385655473df90f3d2797fff9John Stultz		ret = adjtimex(&tx);
143de52133f1892ed2c385655473df90f3d2797fff9John Stultz		if (ret < 0) {
144de52133f1892ed2c385655473df90f3d2797fff9John Stultz			printf("[FAIL]\n");
145de52133f1892ed2c385655473df90f3d2797fff9John Stultz			printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
146de52133f1892ed2c385655473df90f3d2797fff9John Stultz				valid_freq[i], valid_freq[i]>>16);
147de52133f1892ed2c385655473df90f3d2797fff9John Stultz			pass = -1;
148de52133f1892ed2c385655473df90f3d2797fff9John Stultz			goto out;
149de52133f1892ed2c385655473df90f3d2797fff9John Stultz		}
150de52133f1892ed2c385655473df90f3d2797fff9John Stultz		tx.modes = 0;
151de52133f1892ed2c385655473df90f3d2797fff9John Stultz		ret = adjtimex(&tx);
152de52133f1892ed2c385655473df90f3d2797fff9John Stultz		if (tx.freq != valid_freq[i]) {
153de52133f1892ed2c385655473df90f3d2797fff9John Stultz			printf("Warning: freq value %ld not what we set it (%ld)!\n",
154de52133f1892ed2c385655473df90f3d2797fff9John Stultz					tx.freq, valid_freq[i]);
155de52133f1892ed2c385655473df90f3d2797fff9John Stultz		}
156de52133f1892ed2c385655473df90f3d2797fff9John Stultz	}
157de52133f1892ed2c385655473df90f3d2797fff9John Stultz	for (i = 0; i < NUM_FREQ_OUTOFRANGE; i++) {
158de52133f1892ed2c385655473df90f3d2797fff9John Stultz		tx.modes = ADJ_FREQUENCY;
159de52133f1892ed2c385655473df90f3d2797fff9John Stultz		tx.freq = outofrange_freq[i];
160de52133f1892ed2c385655473df90f3d2797fff9John Stultz
161de52133f1892ed2c385655473df90f3d2797fff9John Stultz		ret = adjtimex(&tx);
162de52133f1892ed2c385655473df90f3d2797fff9John Stultz		if (ret < 0) {
163de52133f1892ed2c385655473df90f3d2797fff9John Stultz			printf("[FAIL]\n");
164de52133f1892ed2c385655473df90f3d2797fff9John Stultz			printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
165de52133f1892ed2c385655473df90f3d2797fff9John Stultz				outofrange_freq[i], outofrange_freq[i]>>16);
166de52133f1892ed2c385655473df90f3d2797fff9John Stultz			pass = -1;
167de52133f1892ed2c385655473df90f3d2797fff9John Stultz			goto out;
168de52133f1892ed2c385655473df90f3d2797fff9John Stultz		}
169de52133f1892ed2c385655473df90f3d2797fff9John Stultz		tx.modes = 0;
170de52133f1892ed2c385655473df90f3d2797fff9John Stultz		ret = adjtimex(&tx);
171de52133f1892ed2c385655473df90f3d2797fff9John Stultz		if (tx.freq == outofrange_freq[i]) {
172de52133f1892ed2c385655473df90f3d2797fff9John Stultz			printf("[FAIL]\n");
173de52133f1892ed2c385655473df90f3d2797fff9John Stultz			printf("ERROR: out of range value %ld actually set!\n",
174de52133f1892ed2c385655473df90f3d2797fff9John Stultz					tx.freq);
175de52133f1892ed2c385655473df90f3d2797fff9John Stultz			pass = -1;
176de52133f1892ed2c385655473df90f3d2797fff9John Stultz			goto out;
177de52133f1892ed2c385655473df90f3d2797fff9John Stultz		}
178de52133f1892ed2c385655473df90f3d2797fff9John Stultz	}
179de52133f1892ed2c385655473df90f3d2797fff9John Stultz
180de52133f1892ed2c385655473df90f3d2797fff9John Stultz
181de52133f1892ed2c385655473df90f3d2797fff9John Stultz	if (sizeof(long) == 8) { /* this case only applies to 64bit systems */
182de52133f1892ed2c385655473df90f3d2797fff9John Stultz		for (i = 0; i < NUM_FREQ_INVALID; i++) {
183de52133f1892ed2c385655473df90f3d2797fff9John Stultz			tx.modes = ADJ_FREQUENCY;
184de52133f1892ed2c385655473df90f3d2797fff9John Stultz			tx.freq = invalid_freq[i];
185de52133f1892ed2c385655473df90f3d2797fff9John Stultz			ret = adjtimex(&tx);
186de52133f1892ed2c385655473df90f3d2797fff9John Stultz			if (ret >= 0) {
187de52133f1892ed2c385655473df90f3d2797fff9John Stultz				printf("[FAIL]\n");
188de52133f1892ed2c385655473df90f3d2797fff9John Stultz				printf("Error: No failure on invalid ADJ_FREQUENCY %ld\n",
189de52133f1892ed2c385655473df90f3d2797fff9John Stultz					invalid_freq[i]);
190de52133f1892ed2c385655473df90f3d2797fff9John Stultz				pass = -1;
191de52133f1892ed2c385655473df90f3d2797fff9John Stultz				goto out;
192de52133f1892ed2c385655473df90f3d2797fff9John Stultz			}
193de52133f1892ed2c385655473df90f3d2797fff9John Stultz		}
194de52133f1892ed2c385655473df90f3d2797fff9John Stultz	}
195de52133f1892ed2c385655473df90f3d2797fff9John Stultz
196de52133f1892ed2c385655473df90f3d2797fff9John Stultz	printf("[OK]\n");
197de52133f1892ed2c385655473df90f3d2797fff9John Stultzout:
198de52133f1892ed2c385655473df90f3d2797fff9John Stultz	/* reset freq to zero */
199de52133f1892ed2c385655473df90f3d2797fff9John Stultz	tx.modes = ADJ_FREQUENCY;
200de52133f1892ed2c385655473df90f3d2797fff9John Stultz	tx.freq = 0;
201de52133f1892ed2c385655473df90f3d2797fff9John Stultz	ret = adjtimex(&tx);
202de52133f1892ed2c385655473df90f3d2797fff9John Stultz
203de52133f1892ed2c385655473df90f3d2797fff9John Stultz	return pass;
204de52133f1892ed2c385655473df90f3d2797fff9John Stultz}
205de52133f1892ed2c385655473df90f3d2797fff9John Stultz
206de52133f1892ed2c385655473df90f3d2797fff9John Stultz
207e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultzint set_offset(long long offset, int use_nano)
208e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz{
209e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	struct timex tmx = {};
210e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	int ret;
211e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
212e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	tmx.modes = ADJ_SETOFFSET;
213e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (use_nano) {
214e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		tmx.modes |= ADJ_NANO;
215e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
216e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		tmx.time.tv_sec = offset / NSEC_PER_SEC;
217e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		tmx.time.tv_usec = offset % NSEC_PER_SEC;
218e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
219e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		if (offset < 0 && tmx.time.tv_usec) {
220e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz			tmx.time.tv_sec -= 1;
221e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz			tmx.time.tv_usec += NSEC_PER_SEC;
222e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		}
223e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	} else {
224e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		tmx.time.tv_sec = offset / USEC_PER_SEC;
225e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		tmx.time.tv_usec = offset % USEC_PER_SEC;
226e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
227e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		if (offset < 0 && tmx.time.tv_usec) {
228e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz			tmx.time.tv_sec -= 1;
229e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz			tmx.time.tv_usec += USEC_PER_SEC;
230e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		}
231e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	}
232e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
233e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	ret = clock_adjtime(CLOCK_REALTIME, &tmx);
234e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (ret < 0) {
235e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		printf("(sec: %ld  usec: %ld) ", tmx.time.tv_sec, tmx.time.tv_usec);
236e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		printf("[FAIL]\n");
237e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
238e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	}
239e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	return 0;
240e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz}
241e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
242e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultzint set_bad_offset(long sec, long usec, int use_nano)
243e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz{
244e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	struct timex tmx = {};
245e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	int ret;
246e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
247e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	tmx.modes = ADJ_SETOFFSET;
248e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (use_nano)
249e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		tmx.modes |= ADJ_NANO;
250e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
251e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	tmx.time.tv_sec = sec;
252e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	tmx.time.tv_usec = usec;
253e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	ret = clock_adjtime(CLOCK_REALTIME, &tmx);
254e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (ret >= 0) {
255e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		printf("Invalid (sec: %ld  usec: %ld) did not fail! ", tmx.time.tv_sec, tmx.time.tv_usec);
256e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		printf("[FAIL]\n");
257e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
258e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	}
259e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	return 0;
260e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz}
261e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
262e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultzint validate_set_offset(void)
263e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz{
264e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	printf("Testing ADJ_SETOFFSET... ");
265e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
266e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	/* Test valid values */
267e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(NSEC_PER_SEC - 1, 1))
268e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
269e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
270e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(-NSEC_PER_SEC + 1, 1))
271e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
272e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
273e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(-NSEC_PER_SEC - 1, 1))
274e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
275e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
276e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(5 * NSEC_PER_SEC, 1))
277e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
278e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
279e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(-5 * NSEC_PER_SEC, 1))
280e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
281e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
282e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(5 * NSEC_PER_SEC + NSEC_PER_SEC / 2, 1))
283e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
284e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
285e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(-5 * NSEC_PER_SEC - NSEC_PER_SEC / 2, 1))
286e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
287e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
288e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(USEC_PER_SEC - 1, 0))
289e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
290e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
291e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(-USEC_PER_SEC + 1, 0))
292e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
293e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
294e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(-USEC_PER_SEC - 1, 0))
295e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
296e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
297e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(5 * USEC_PER_SEC, 0))
298e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
299e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
300e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(-5 * USEC_PER_SEC, 0))
301e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
302e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
303e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(5 * USEC_PER_SEC + USEC_PER_SEC / 2, 0))
304e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
305e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
306e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_offset(-5 * USEC_PER_SEC - USEC_PER_SEC / 2, 0))
307e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
308e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
309e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	/* Test invalid values */
310e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_bad_offset(0, -1, 1))
311e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
312e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_bad_offset(0, -1, 0))
313e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
314e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_bad_offset(0, 2 * NSEC_PER_SEC, 1))
315e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
316e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_bad_offset(0, 2 * USEC_PER_SEC, 0))
317e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
318e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_bad_offset(0, NSEC_PER_SEC, 1))
319e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
320e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_bad_offset(0, USEC_PER_SEC, 0))
321e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
322e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_bad_offset(0, -NSEC_PER_SEC, 1))
323e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
324e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (set_bad_offset(0, -USEC_PER_SEC, 0))
325e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return -1;
326e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
327e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	printf("[OK]\n");
328e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	return 0;
329e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz}
330e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
331de52133f1892ed2c385655473df90f3d2797fff9John Stultzint main(int argc, char **argv)
332de52133f1892ed2c385655473df90f3d2797fff9John Stultz{
333de52133f1892ed2c385655473df90f3d2797fff9John Stultz	if (validate_freq())
334de52133f1892ed2c385655473df90f3d2797fff9John Stultz		return ksft_exit_fail();
335de52133f1892ed2c385655473df90f3d2797fff9John Stultz
336e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz	if (validate_set_offset())
337e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz		return ksft_exit_fail();
338e03a58c320e1103ebe97bda8ebdfcc5c9829c53fJohn Stultz
339de52133f1892ed2c385655473df90f3d2797fff9John Stultz	return ksft_exit_pass();
340de52133f1892ed2c385655473df90f3d2797fff9John Stultz}
341