Add support for ADJ_OFFSET_SS_READ mode
Also assume that kernels >= 2.6.27 don't need frequency scaling.
This commit is contained in:
parent
75330fdff5
commit
032d1db883
4 changed files with 39 additions and 10 deletions
|
@ -39,6 +39,7 @@ struct timex {
|
|||
#define ADJ_STATUS 0x0010 /* clock status */
|
||||
#define ADJ_TICK 0x4000 /* tick value */
|
||||
#define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */
|
||||
#define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime */
|
||||
|
||||
#define SHIFT_USEC 16 /* frequency offset scale (shift) */
|
||||
|
||||
|
|
34
sys_linux.c
34
sys_linux.c
|
@ -103,10 +103,11 @@ static int version_major;
|
|||
static int version_minor;
|
||||
static int version_patchlevel;
|
||||
|
||||
/* Flag indicating whether adjtimex() with txc.modes equal to zero
|
||||
returns the remaining time adjustment or not. If not we have to read
|
||||
the outstanding adjustment by setting it to zero, examining the return
|
||||
value and setting the outstanding adjustment back again. */
|
||||
/* Flag indicating whether adjtimex() returns the remaining time adjustment
|
||||
or not. If not we have to read the outstanding adjustment by setting it to
|
||||
zero, examining the return value and setting the outstanding adjustment back
|
||||
again. If 1, txc.modes equal to zero is used to read the time. If 2,
|
||||
txc.modes is set to ADJ_OFFSET_SS_READ. */
|
||||
|
||||
static int have_readonly_adjtime;
|
||||
|
||||
|
@ -532,11 +533,20 @@ get_offset_correction(struct timeval *raw,
|
|||
double fast_slew_remaining;
|
||||
long offset;
|
||||
|
||||
if (have_readonly_adjtime) {
|
||||
if (TMX_GetOffsetLeft(&offset) < 0) {
|
||||
again:
|
||||
if (have_readonly_adjtime == 1) {
|
||||
if (TMX_GetOffsetLeftOld(&offset) < 0) {
|
||||
CROAK("adjtimex() failed in get_offset_correction");
|
||||
}
|
||||
|
||||
adjtime_left = (double)offset / 1.0e6;
|
||||
} else if (have_readonly_adjtime == 2) {
|
||||
if (TMX_GetOffsetLeft(&offset) < 0) {
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "adjtimex() doesn't support ADJ_OFFSET_SS_READ");
|
||||
have_readonly_adjtime = 0;
|
||||
goto again;
|
||||
}
|
||||
|
||||
adjtime_left = (double)offset / 1.0e6;
|
||||
} else {
|
||||
offset = 0;
|
||||
|
@ -796,13 +806,19 @@ get_version_specific_details(void)
|
|||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
if (minor < 6 || patch < 27) {
|
||||
/* These seem to be like 2.0.32 */
|
||||
freq_scale = (hz==100) ? (128.0 / 128.125) : basic_freq_scale;
|
||||
have_readonly_adjtime = 0;
|
||||
break;
|
||||
}
|
||||
/* Let's be optimistic that these will be the same until proven
|
||||
otherwise :-) */
|
||||
case 7:
|
||||
case 8:
|
||||
/* These seem to be like 2.0.32 */
|
||||
freq_scale = (hz==100) ? (128.0 / 128.125) : basic_freq_scale;
|
||||
have_readonly_adjtime = 0;
|
||||
/* These don't need scaling */
|
||||
freq_scale = 1.0;
|
||||
have_readonly_adjtime = 2;
|
||||
break;
|
||||
default:
|
||||
LOG_FATAL(LOGF_SysLinux, "Kernel version not supported yet, sorry.");
|
||||
|
|
|
@ -93,7 +93,7 @@ TMX_GetFrequency(double *freq)
|
|||
}
|
||||
|
||||
int
|
||||
TMX_GetOffsetLeft(long *offset)
|
||||
TMX_GetOffsetLeftOld(long *offset)
|
||||
{
|
||||
struct timex txc;
|
||||
int result;
|
||||
|
@ -103,6 +103,17 @@ TMX_GetOffsetLeft(long *offset)
|
|||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
TMX_GetOffsetLeft(long *offset)
|
||||
{
|
||||
struct timex txc;
|
||||
int result;
|
||||
txc.modes = ADJ_OFFSET_SS_READ;
|
||||
result = adjtimex(&txc);
|
||||
*offset = txc.offset;
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
TMX_ReadCurrentParams(struct tmx_params *params)
|
||||
{
|
||||
|
|
|
@ -72,6 +72,7 @@ int TMX_SetTick(long tick);
|
|||
int TMX_ApplyOffset(long *offset);
|
||||
int TMX_SetFrequency(double freq, long tick);
|
||||
int TMX_GetFrequency(double *freq);
|
||||
int TMX_GetOffsetLeftOld(long *offset);
|
||||
int TMX_GetOffsetLeft(long *offset);
|
||||
int TMX_ReadCurrentParams(struct tmx_params *params);
|
||||
int TMX_SetLeap(int leap);
|
||||
|
|
Loading…
Reference in a new issue