18c2ecf20Sopenharmony_ci/* ADJ_FREQ Skew change test
28c2ecf20Sopenharmony_ci *		by: john stultz (johnstul@us.ibm.com)
38c2ecf20Sopenharmony_ci *		(C) Copyright IBM 2012
48c2ecf20Sopenharmony_ci *		Licensed under the GPLv2
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci *  NOTE: This is a meta-test which cranks the ADJ_FREQ knob and
78c2ecf20Sopenharmony_ci *  then uses other tests to detect problems. Thus this test requires
88c2ecf20Sopenharmony_ci *  that the raw_skew, inconsistency-check and nanosleep tests be
98c2ecf20Sopenharmony_ci *  present in the same directory it is run from.
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci *  To build:
128c2ecf20Sopenharmony_ci *	$ gcc change_skew.c -o change_skew -lrt
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci *   This program is free software: you can redistribute it and/or modify
158c2ecf20Sopenharmony_ci *   it under the terms of the GNU General Public License as published by
168c2ecf20Sopenharmony_ci *   the Free Software Foundation, either version 2 of the License, or
178c2ecf20Sopenharmony_ci *   (at your option) any later version.
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci *   This program is distributed in the hope that it will be useful,
208c2ecf20Sopenharmony_ci *   but WITHOUT ANY WARRANTY; without even the implied warranty of
218c2ecf20Sopenharmony_ci *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
228c2ecf20Sopenharmony_ci *   GNU General Public License for more details.
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#include <stdio.h>
278c2ecf20Sopenharmony_ci#include <stdlib.h>
288c2ecf20Sopenharmony_ci#include <sys/time.h>
298c2ecf20Sopenharmony_ci#include <sys/timex.h>
308c2ecf20Sopenharmony_ci#include <time.h>
318c2ecf20Sopenharmony_ci#include "../kselftest.h"
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#define NSEC_PER_SEC 1000000000LL
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ciint change_skew_test(int ppm)
378c2ecf20Sopenharmony_ci{
388c2ecf20Sopenharmony_ci	struct timex tx;
398c2ecf20Sopenharmony_ci	int ret;
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	tx.modes = ADJ_FREQUENCY;
428c2ecf20Sopenharmony_ci	tx.freq = ppm << 16;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	ret = adjtimex(&tx);
458c2ecf20Sopenharmony_ci	if (ret < 0) {
468c2ecf20Sopenharmony_ci		printf("Error adjusting freq\n");
478c2ecf20Sopenharmony_ci		return ret;
488c2ecf20Sopenharmony_ci	}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	ret = system("./raw_skew");
518c2ecf20Sopenharmony_ci	ret |= system("./inconsistency-check");
528c2ecf20Sopenharmony_ci	ret |= system("./nanosleep");
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	return ret;
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ciint main(int argv, char **argc)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	struct timex tx;
618c2ecf20Sopenharmony_ci	int i, ret;
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	int ppm[5] = {0, 250, 500, -250, -500};
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	/* Kill ntpd */
668c2ecf20Sopenharmony_ci	ret = system("killall -9 ntpd");
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	/* Make sure there's no offset adjustment going on */
698c2ecf20Sopenharmony_ci	tx.modes = ADJ_OFFSET;
708c2ecf20Sopenharmony_ci	tx.offset = 0;
718c2ecf20Sopenharmony_ci	ret = adjtimex(&tx);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	if (ret < 0) {
748c2ecf20Sopenharmony_ci		printf("Maybe you're not running as root?\n");
758c2ecf20Sopenharmony_ci		return -1;
768c2ecf20Sopenharmony_ci	}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	for (i = 0; i < 5; i++) {
798c2ecf20Sopenharmony_ci		printf("Using %i ppm adjustment\n", ppm[i]);
808c2ecf20Sopenharmony_ci		ret = change_skew_test(ppm[i]);
818c2ecf20Sopenharmony_ci		if (ret)
828c2ecf20Sopenharmony_ci			break;
838c2ecf20Sopenharmony_ci	}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	/* Set things back */
868c2ecf20Sopenharmony_ci	tx.modes = ADJ_FREQUENCY;
878c2ecf20Sopenharmony_ci	tx.offset = 0;
888c2ecf20Sopenharmony_ci	adjtimex(&tx);
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	if (ret) {
918c2ecf20Sopenharmony_ci		printf("[FAIL]");
928c2ecf20Sopenharmony_ci		return ksft_exit_fail();
938c2ecf20Sopenharmony_ci	}
948c2ecf20Sopenharmony_ci	printf("[OK]");
958c2ecf20Sopenharmony_ci	return ksft_exit_pass();
968c2ecf20Sopenharmony_ci}
97