Merge branch 'hwclock-date7-3' of github.com:jwpi/util-linux

* 'hwclock-date7-3' of github.com:jwpi/util-linux:
  hwclock: remove unused 'silent' arg
  hwclock: remove dead cmos code
  hwclock: improve cmos message strings
  hwclock: remove unused atomic arg in cmos
  hwclock: remove unused cmos ctl structs
  hwclock: remove alpha cmos
This commit is contained in:
Karel Zak 2017-04-04 14:41:50 +02:00
commit c9700fc156
5 changed files with 119 additions and 471 deletions

View File

@ -76,17 +76,8 @@ static int inb(int c __attribute__((__unused__)))
return 0;
}
# endif /* __i386__ __x86_64__ */
#elif defined(__alpha__)
# ifdef HAVE_SYS_IO_H
# include <sys/io.h>
# else
/* <asm/io.h> fails to compile, probably because of u8 etc */
extern unsigned int inb(unsigned long port);
extern void outb(unsigned char b, unsigned long port);
extern int iopl(int level);
# endif
#else /* __alpha__ */
# warning "disable cmos access - not i386, x86_64, or alpha"
#else
# warning "disable cmos access - not i386 or x86_64"
static void outb(int a __attribute__((__unused__)),
int b __attribute__((__unused__)))
{
@ -106,286 +97,60 @@ static int inb(int c __attribute__((__unused__)))
#define IOPL_NOT_IMPLEMENTED -2
/*
* The epoch.
*
* Unix uses 1900 as epoch for a struct tm, and 1970 for a time_t. But what
* was written to CMOS?
*
* Digital DECstations use 1928 - this is on a mips or alpha Digital Unix
* uses 1952, e.g. on AXPpxi33. Windows NT uses 1980. The ARC console
* expects to boot Windows NT and uses 1980. (But a Ruffian uses 1900, just
* like SRM.) It is reported that ALPHA_PRE_V1_2_SRM_CONSOLE uses 1958.
* POSIX uses 1900 as epoch for a struct tm, and 1970 for a time_t.
*/
#define TM_EPOCH 1900
static int cmos_epoch = 1900;
/*
* Martin Ostermann writes:
*
* The problem with the Jensen is twofold: First, it has the clock at a
* different address. Secondly, it has a distinction between "local" and
* normal bus addresses. The local ones pertain to the hardware integrated
* into the chipset, like serial/parallel ports and of course, the RTC.
* Those need to be addressed differently. This is handled fine in the
* kernel, and it's not a problem, since this usually gets totally optimized
* by the compile. But the i/o routines of (g)libc lack this support so far.
* The result of this is, that the old clock program worked only on the
* Jensen when USE_DEV_PORT was defined, but not with the normal inb/outb
* functions.
*/
static int use_dev_port = 0; /* 1 for Jensen */
static int dev_port_fd;
static unsigned short clock_ctl_addr = 0x70; /* 0x170 for Jensen */
static unsigned short clock_data_addr = 0x71; /* 0x171 for Jensen */
static int century_byte = 0; /* 0: don't access a century byte
* 50 (0x32): usual PC value
* 55 (0x37): PS/2
*/
#ifdef __alpha__
static int funkyTOY = 0; /* 1 for PC164/LX164/SX164 type alpha */
#endif
#ifdef __alpha
static int is_in_cpuinfo(char *fmt, char *str)
{
FILE *cpuinfo;
char field[256];
char format[sizeof(field)];
int found = 0;
sprintf(format, "%s : %s", fmt, "%255s");
cpuinfo = fopen(_PATH_PROC_CPUINFO, "r");
if (cpuinfo) {
do {
if (fscanf(cpuinfo, format, field) == 1) {
if (strncmp(field, str, strlen(str)) == 0)
found = 1;
break;
}
} while (fgets(field, 256, cpuinfo));
fclose(cpuinfo);
}
return found;
}
/*
* Set cmos_epoch, either from user options, or by asking the kernel, or by
* looking at /proc/cpu_info
*/
void set_cmos_epoch(const struct hwclock_control *ctl)
{
unsigned long epoch;
/* Believe the user */
if (ctl->epoch_option) {
cmos_epoch = ctl->epoch_option;
return;
}
if (ctl->ARCconsole)
cmos_epoch = 1980;
if (ctl->ARCconsole || ctl->SRM)
return;
#ifdef __linux__
/*
* If we can ask the kernel, we don't need guessing from
* /proc/cpuinfo
*/
if (get_epoch_rtc(ctl, &epoch, 1) == 0) {
cmos_epoch = epoch;
return;
}
#endif
/*
* The kernel source today says: read the year.
*
* If it is in 0-19 then the epoch is 2000.
* If it is in 20-47 then the epoch is 1980.
* If it is in 48-69 then the epoch is 1952.
* If it is in 70-99 then the epoch is 1928.
*
* Otherwise the epoch is 1900.
* TODO: Clearly, this must be changed before 2019.
*/
/*
* See whether we are dealing with SRM or MILO, as they have
* different "epoch" ideas.
*/
if (is_in_cpuinfo("system serial number", "MILO")) {
if (ctl->debug)
printf(_("booted from MILO\n"));
/*
* See whether we are dealing with a RUFFIAN aka Alpha PC-164
* UX (or BX), as they have REALLY different TOY (TimeOfYear)
* format: BCD, and not an ARC-style epoch. BCD is detected
* dynamically, but we must NOT adjust like ARC.
*/
if (is_in_cpuinfo("system type", "Ruffian")) {
if (debug)
printf(_("Ruffian BCD clock\n"));
return;
}
}
cmos_epoch = 1980;
}
void set_cmos_access(const struct hwclock_control *ctl)
{
/*
* See whether we're dealing with a Jensen---it has a weird I/O
* system. DEC was just learning how to build Alpha PCs.
*/
if (ctl->Jensen || is_in_cpuinfo("system type", "Jensen")) {
use_dev_port = 1;
clock_ctl_addr = 0x170;
clock_data_addr = 0x171;
if (ctl->debug)
printf(_("clockport adjusted to 0x%x\n"),
clock_ctl_addr);
}
/*
* See whether we are dealing with PC164/LX164/SX164, as they have a
* TOY that must be accessed differently to work correctly.
*/
/* Nautilus stuff reported by Neoklis Kyriazis */
if (ctl->funky_toy ||
is_in_cpuinfo("system variation", "PC164") ||
is_in_cpuinfo("system variation", "LX164") ||
is_in_cpuinfo("system variation", "SX164") ||
is_in_cpuinfo("system type", "Nautilus")) {
funkyTOY = 1;
if (ctl->debug)
printf(_("funky TOY!\n"));
}
}
#endif /* __alpha */
#ifdef __alpha__
/*
* The Alpha doesn't allow user-level code to disable interrupts (for good
* reasons). Instead, we ensure atomic operation by performing the operation
* and checking whether the high 32 bits of the cycle counter changed. If
* they did, a context switch must have occurred and we redo the operation.
* As long as the operation is reasonably short, it will complete
* atomically, eventually.
*/
static unsigned long
atomic(const char *name,
unsigned long (*op) (const struct hwclock_control *ctl, unsigned long),
const struct hwclock_control *ctl,
unsigned long arg)
{
unsigned long ts1, ts2, n, v;
for (n = 0; n < 1000; ++n) {
asm volatile ("rpcc %0":"r=" (ts1));
v = (*op) (ctl, arg);
asm volatile ("rpcc %0":"r=" (ts2));
if ((ts1 ^ ts2) >> 32 == 0) {
return v;
}
}
errx(EXIT_FAILURE, _("atomic %s failed for 1000 iterations!"),
name);
}
#else
static unsigned short clock_ctl_addr = 0x70;
static unsigned short clock_data_addr = 0x71;
/*
* Hmmh, this isn't very atomic. Maybe we should force an error instead?
*
* TODO: optimize the access to CMOS by mlockall(MCL_CURRENT) and SCHED_FIFO
*/
static unsigned long
atomic(const char *name __attribute__ ((__unused__)),
unsigned long (*op) (const struct hwclock_control *ctl, unsigned long),
const struct hwclock_control *ctl,
unsigned long arg)
static unsigned long atomic(unsigned long (*op) (unsigned long),
unsigned long arg)
{
return (*op) (ctl, arg);
return (*op) (arg);
}
#endif
/*
* We only want to read CMOS data, but unfortunately writing to bit 7
* disables (1) or enables (0) NMI; since this bit is read-only we have
* to guess the old status. Various docs suggest that one should disable
* NMI while reading/writing CMOS data, and enable it again afterwards.
* This would yield the sequence
*
* outb (reg | 0x80, 0x70);
* val = inb(0x71);
* outb (0x0d, 0x70); // 0x0d: random read-only location
*
* Other docs state that "any write to 0x70 should be followed by an
* action to 0x71 or the RTC will be left in an unknown state". Most
* docs say that it doesn't matter at all what one does.
*
* bit 0x80: disable NMI while reading - should we? Let us follow the
* kernel and not disable. Called only with 0 <= reg < 128
*/
static inline unsigned long cmos_read(const struct hwclock_control *ctl,
unsigned long reg)
static inline unsigned long cmos_read(unsigned long reg)
{
if (use_dev_port) {
unsigned char v = reg | 0x80;
lseek(dev_port_fd, clock_ctl_addr, 0);
if (write(dev_port_fd, &v, 1) == -1 && ctl->debug)
warn(_("cmos_read(): write to control address %X failed"),
clock_ctl_addr);
lseek(dev_port_fd, clock_data_addr, 0);
if (read(dev_port_fd, &v, 1) == -1 && ctl->debug)
warn(_("cmos_read(): read from data address %X failed"),
clock_data_addr);
return v;
} else {
/*
* We only want to read CMOS data, but unfortunately writing
* to bit 7 disables (1) or enables (0) NMI; since this bit
* is read-only we have to guess the old status. Various
* docs suggest that one should disable NMI while
* reading/writing CMOS data, and enable it again
* afterwards. This would yield the sequence
*
* outb (reg | 0x80, 0x70);
* val = inb(0x71);
* outb (0x0d, 0x70); // 0x0d: random read-only location
*
* Other docs state that "any write to 0x70 should be
* followed by an action to 0x71 or the RTC will be left in
* an unknown state". Most docs say that it doesn't matter at
* all what one does.
*/
/*
* bit 0x80: disable NMI while reading - should we? Let us
* follow the kernel and not disable. Called only with 0 <=
* reg < 128
*/
outb(reg, clock_ctl_addr);
return inb(clock_data_addr);
}
outb(reg, clock_ctl_addr);
return inb(clock_data_addr);
}
static inline unsigned long cmos_write(const struct hwclock_control *ctl,
unsigned long reg, unsigned long val)
static inline unsigned long cmos_write(unsigned long reg, unsigned long val)
{
if (use_dev_port) {
unsigned char v = reg | 0x80;
lseek(dev_port_fd, clock_ctl_addr, 0);
if (write(dev_port_fd, &v, 1) == -1 && ctl->debug)
warn(_("cmos_write(): write to control address %X failed"),
clock_ctl_addr);
v = (val & 0xff);
lseek(dev_port_fd, clock_data_addr, 0);
if (write(dev_port_fd, &v, 1) == -1 && ctl->debug)
warn(_("cmos_write(): write to data address %X failed"),
clock_data_addr);
} else {
outb(reg, clock_ctl_addr);
outb(val, clock_data_addr);
}
outb(reg, clock_ctl_addr);
outb(val, clock_data_addr);
return 0;
}
static unsigned long cmos_set_time(const struct hwclock_control *ctl,
unsigned long arg)
static unsigned long cmos_set_time(unsigned long arg)
{
unsigned char save_control, save_freq_select, pmbit = 0;
struct tm tm = *(struct tm *)arg;
unsigned int century;
/*
* CMOS byte 10 (clock status register A) has 3 bitfields:
@ -404,14 +169,11 @@ static unsigned long cmos_set_time(const struct hwclock_control *ctl,
* 1111 500 milliseconds (maximum, 2 Hz)
* 0110 976.562 microseconds (default 1024 Hz)
*/
save_control = cmos_read(ctl, 11); /* tell the clock it's being set */
cmos_write(ctl, 11, (save_control | 0x80));
save_freq_select = cmos_read(ctl, 10); /* stop and reset prescaler */
cmos_write(ctl, 10, (save_freq_select | 0x70));
save_control = cmos_read(11); /* tell the clock it's being set */
cmos_write(11, (save_control | 0x80));
save_freq_select = cmos_read(10); /* stop and reset prescaler */
cmos_write(10, (save_freq_select | 0x70));
tm.tm_year += TM_EPOCH;
century = tm.tm_year / 100;
tm.tm_year -= cmos_epoch;
tm.tm_year %= 100;
tm.tm_mon += 1;
tm.tm_wday += 1;
@ -433,18 +195,15 @@ static unsigned long cmos_set_time(const struct hwclock_control *ctl,
BIN_TO_BCD(tm.tm_mday);
BIN_TO_BCD(tm.tm_mon);
BIN_TO_BCD(tm.tm_year);
BIN_TO_BCD(century);
}
cmos_write(ctl, 0, tm.tm_sec);
cmos_write(ctl, 2, tm.tm_min);
cmos_write(ctl, 4, tm.tm_hour | pmbit);
cmos_write(ctl, 6, tm.tm_wday);
cmos_write(ctl, 7, tm.tm_mday);
cmos_write(ctl, 8, tm.tm_mon);
cmos_write(ctl, 9, tm.tm_year);
if (century_byte)
cmos_write(ctl, century_byte, century);
cmos_write(0, tm.tm_sec);
cmos_write(2, tm.tm_min);
cmos_write(4, tm.tm_hour | pmbit);
cmos_write(6, tm.tm_wday);
cmos_write(7, tm.tm_mday);
cmos_write(8, tm.tm_mon);
cmos_write(9, tm.tm_year);
/*
* The kernel sources, linux/arch/i386/kernel/time.c, have the
@ -457,30 +216,26 @@ static unsigned long cmos_set_time(const struct hwclock_control *ctl,
* the Dallas Semiconductor data sheets, but who believes data
* sheets anyway ... -- Markus Kuhn
*/
cmos_write(ctl, 11, save_control);
cmos_write(ctl, 10, save_freq_select);
cmos_write(11, save_control);
cmos_write(10, save_freq_select);
return 0;
}
static int hclock_read(const struct hwclock_control *ctl, unsigned long reg)
static int hclock_read(unsigned long reg)
{
return atomic("clock read", cmos_read, ctl, reg);
return atomic(cmos_read, reg);
}
static void hclock_set_time(const struct hwclock_control *ctl, const struct tm *tm)
static void hclock_set_time(const struct tm *tm)
{
atomic("set time", cmos_set_time, ctl, (unsigned long)(tm));
atomic(cmos_set_time, (unsigned long)(tm));
}
static inline int cmos_clock_busy(const struct hwclock_control *ctl)
static inline int cmos_clock_busy(void)
{
return
#ifdef __alpha__
/* poll bit 4 (UF) of Control Register C */
funkyTOY ? (hclock_read(ctl, 12) & 0x10) :
#endif
/* poll bit 7 (UIP) of Control Register A */
(hclock_read(ctl, 10) & 0x80);
(hclock_read(10) & 0x80);
}
static int synchronize_to_clock_tick_cmos(const struct hwclock_control *ctl
@ -493,12 +248,12 @@ static int synchronize_to_clock_tick_cmos(const struct hwclock_control *ctl
* weird happens, we have a limit on this loop to reduce the impact
* of this failure.
*/
for (i = 0; !cmos_clock_busy(ctl); i++)
for (i = 0; !cmos_clock_busy(); i++)
if (i >= 10000000)
return 1;
/* Wait for fall. Should be within 2.228 ms. */
for (i = 0; cmos_clock_busy(ctl); i++)
for (i = 0; cmos_clock_busy(); i++)
if (i >= 1000000)
return 1;
return 0;
@ -541,25 +296,21 @@ static int read_hardware_clock_cmos(const struct hwclock_control *ctl
* at first, the clock has changed while we were running. We
* check for that too, and if it happens, we start over.
*/
if (!cmos_clock_busy(ctl)) {
if (!cmos_clock_busy()) {
/* No clock update in progress, go ahead and read */
tm->tm_sec = hclock_read(ctl, 0);
tm->tm_min = hclock_read(ctl, 2);
tm->tm_hour = hclock_read(ctl, 4);
tm->tm_wday = hclock_read(ctl, 6);
tm->tm_mday = hclock_read(ctl, 7);
tm->tm_mon = hclock_read(ctl, 8);
tm->tm_year = hclock_read(ctl, 9);
status = hclock_read(ctl, 11);
#if 0
if (century_byte)
century = hclock_read(ctl, century_byte);
#endif
tm->tm_sec = hclock_read(0);
tm->tm_min = hclock_read(2);
tm->tm_hour = hclock_read(4);
tm->tm_wday = hclock_read(6);
tm->tm_mday = hclock_read(7);
tm->tm_mon = hclock_read(8);
tm->tm_year = hclock_read(9);
status = hclock_read(11);
/*
* Unless the clock changed while we were reading,
* consider this a good clock read .
*/
if (tm->tm_sec == hclock_read(ctl, 0))
if (tm->tm_sec == hclock_read(0))
got_time = TRUE;
}
/*
@ -578,9 +329,6 @@ static int read_hardware_clock_cmos(const struct hwclock_control *ctl
BCD_TO_BIN(tm->tm_mday);
BCD_TO_BIN(tm->tm_mon);
BCD_TO_BIN(tm->tm_year);
#if 0
BCD_TO_BIN(century);
#endif
}
/*
@ -594,7 +342,6 @@ static int read_hardware_clock_cmos(const struct hwclock_control *ctl
*/
tm->tm_wday -= 1;
tm->tm_mon -= 1;
tm->tm_year += (cmos_epoch - TM_EPOCH);
if (tm->tm_year < 69)
tm->tm_year += 100;
if (pmbit) {
@ -611,12 +358,11 @@ static int set_hardware_clock_cmos(const struct hwclock_control *ctl
__attribute__((__unused__)),
const struct tm *new_broken_time)
{
hclock_set_time(ctl, new_broken_time);
hclock_set_time(new_broken_time);
return 0;
}
#if defined(__i386__) || defined(__alpha__) || defined(__x86_64__)
#if defined(__i386__) || defined(__x86_64__)
# if defined(HAVE_IOPL)
static int i386_iopl(const int level)
{
@ -640,29 +386,20 @@ static int get_permissions_cmos(void)
{
int rc;
if (use_dev_port) {
if ((dev_port_fd = open(_PATH_DEV_PORT, O_RDWR)) < 0) {
warn(_("cannot open %s"), _PATH_DEV_PORT);
rc = 1;
} else
rc = 0;
} else {
rc = i386_iopl(3);
if (rc == IOPL_NOT_IMPLEMENTED) {
warnx(_("I failed to get permission because I didn't try."));
} else if (rc != 0) {
rc = errno;
warn(_("unable to get I/O port access: "
"the iopl(3) call failed"));
if (rc == EPERM && geteuid())
warnx(_("Probably you need root privileges.\n"));
}
rc = i386_iopl(3);
if (rc == IOPL_NOT_IMPLEMENTED) {
warnx(_("ISA port access is not implemented"));
} else if (rc != 0) {
rc = errno;
warn(_("iopl() port access failed"));
if (rc == EPERM && geteuid())
warnx(_("root privileges may be required"));
}
return rc ? 1 : 0;
}
static struct clock_ops cmos_interface = {
N_("Using direct I/O instructions to ISA clock."),
N_("Using direct ISA access to the clock"),
get_permissions_cmos,
read_hardware_clock_cmos,
set_hardware_clock_cmos,
@ -676,7 +413,7 @@ static struct clock_ops cmos_interface = {
struct clock_ops *probe_for_cmos_clock(void)
{
static const int have_cmos =
#if defined(__i386__) || defined(__alpha__) || defined(__x86_64__)
#if defined(__i386__) || defined(__x86_64__)
TRUE;
#else
FALSE;

View File

@ -396,27 +396,23 @@ struct clock_ops *probe_for_rtc_clock(const struct hwclock_control *ctl)
/*
* Get the Hardware Clock epoch setting from the kernel.
*/
int get_epoch_rtc(const struct hwclock_control *ctl, unsigned long *epoch_p,
int silent)
int get_epoch_rtc(const struct hwclock_control *ctl, unsigned long *epoch_p)
{
int rtc_fd;
rtc_fd = open_rtc(ctl);
if (rtc_fd < 0) {
if (!silent) {
if (errno == ENOENT)
warnx(_
("To manipulate the epoch value in the kernel, we must "
"access the Linux 'rtc' device driver via the device special "
"file. This file does not exist on this system."));
else
warn(_("cannot open rtc device"));
}
if (errno == ENOENT)
warnx(_
("To manipulate the epoch value in the kernel, we must "
"access the Linux 'rtc' device driver via the device special "
"file. This file does not exist on this system."));
else
warn(_("cannot open rtc device"));
return 1;
}
if (ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p) == -1) {
if (!silent)
warn(_("ioctl(RTC_EPOCH_READ) to %s failed"),
rtc_dev_name);
return 1;

View File

@ -44,22 +44,30 @@ discussion below, under
.B \-\-getepoch
.TQ
.B \-\-setepoch
These functions are for Alpha machines only.
These functions are for Alpha machines only, and are only available
through the Linux kernel RTC driver.
.sp
Read and set the kernel's Hardware Clock epoch value.
They are used to read and set the kernel's Hardware Clock epoch value.
Epoch is the number of years into AD to which a zero year value in the
Hardware Clock refers. For example, if you are using the convention
that the year counter in your Hardware Clock contains the number of
full years since 1952, then the kernel's Hardware Clock epoch value
must be 1952.
Hardware Clock refers. For example, if the machine's BIOS sets the year
counter in the Hardware Clock to contain the number of full years since
1952, then the kernel's Hardware Clock epoch value must be 1952.
.sp
The \fB\%\-\-setepoch\fR function requires using the
.B \%\-\-epoch
option to specify the year.
.sp
option to specify the year. For example:
.RS
.IP "" 4
.B hwclock\ \-\-setepoch\ \-\-epoch=1952
.PP
The RTC driver attempts to guess the correct epoch value, so setting it
may not be required.
.PP
This epoch value is used whenever
.B \%hwclock
reads or sets the Hardware Clock.
reads or sets the Hardware Clock on an Alpha machine. For ISA machines
the kernel uses the fixed Hardware Clock epoch of 1900.
.RE
.
.TP
.B \-\-predict
@ -278,23 +286,27 @@ can help you understand how the program works.
.
.TP
.B \-\-directisa
This option is meaningful for: ISA compatible machines including x86, and
x86_64; and Alpha (which has a similar Hardware Clock interface). For other
machines, it has no effect. This option tells
This option is meaningful for ISA compatible machines in the x86 and
x86_64 family. For other machines, it has no effect. This option tells
.B \%hwclock
to use explicit I/O instructions to access the Hardware Clock.
Without this option,
.B \%hwclock
will use the rtc device, which it assumes to be driven by the RTC device
driver. As of v2.26 it will no longer automatically use directisa when
the rtc driver is unavailable; this was causing an unsafe condition that
could allow two processes to access the Hardware Clock at the same time.
Direct hardware access from userspace should only be used for testing,
troubleshooting, and as a last resort when all other methods fail. See
the
will use the rtc device file, which it assumes to be driven by the Linux
RTC device driver. As of v2.26 it will no longer automatically use
directisa when the rtc driver is unavailable; this was causing an unsafe
condition that could allow two processes to access the Hardware Clock at
the same time. Direct hardware access from userspace should only be
used for testing, troubleshooting, and as a last resort when all other
methods fail. See the
.BR \-\-rtc " option."
.
.TP
.BI \-\-epoch= year
This option is required when using the
.BR \%\-\-setepoch \ function.
.
.TP
.BR \-f , \ \-\-rtc=\fIfilename\fR
.RB "Override " \%hwclock 's
default rtc device file name. Otherwise it will
@ -402,55 +414,6 @@ option to be used. See the discussion below, under
.BR "The Adjust Function" .
.RE
.
.SH OPTIONS FOR ALPHA MACHINES ONLY
.
.TP
.B \-\-arc
This option is equivalent to
.B \%\-\-epoch=1980
and is used to specify the most common epoch on Alphas
with an ARC console (although Ruffians have an epoch of 1900).
.
.TP
.BI \-\-epoch= year
Specifies the year which is the beginning of the Hardware Clock's epoch,
that is the number of years into AD to which a zero value in the
Hardware Clock's year counter refers. It is used together with the
.B \%\-\-setepoch
option to set the kernel's idea of the epoch of the Hardware Clock.
.sp
For example, on a Digital Unix machine:
.RS
.IP "" 4
.B hwclock\ \-\-setepoch\ \-\-epoch=1952
.RE
.
.TP
.B \-\-funky\-toy
.TQ
.B \-\-jensen
These two options specify what kind of Alpha machine you have. They
are invalid if you do not have an Alpha and are usually unnecessary
if you do;
.B \%hwclock
should be able to determine what it is running on when
.I \%/proc
is mounted.
.sp
.RB "The " \%\-\-jensen
option is used for Jensen models;
.B \%\-\-funky\-toy
means that the machine requires the UF bit instead of the UIP bit in
the Hardware Clock to detect a time transition. The "toy" in the option
name refers to the Time Of Year facility of the machine.
.
.TP
.B \-\-srm
This option is equivalent to
.B \%\-\-epoch=1900
and is used to specify the most common epoch on Alphas
with an SRM console.
.
.SH NOTES
.
.SS Clocks in a Linux System
@ -566,15 +529,8 @@ reasons that userspace programs are generally not supposed to do
direct I/O and disable interrupts.
.B \%hwclock
provides it for testing, troubleshooting, and because it may be the
only method available on ISA compatible and Alpha systems which do not
have a working rtc device driver.
.PP
In the case of a Jensen Alpha, there is no way for
.B \%hwclock
to execute those I/O instructions, and so it uses instead the
.I \%/dev/port
device special file, which provides almost as low-level an interface to
the I/O subsystem.
only method available on ISA systems which do not have a working rtc
device driver.
.PP
On an m68k system,
.B \%hwclock

View File

@ -1190,7 +1190,7 @@ manipulate_epoch(const struct hwclock_control *ctl)
if (ctl->getepoch) {
unsigned long epoch;
if (get_epoch_rtc(ctl, &epoch, 0))
if (get_epoch_rtc(ctl, &epoch))
warnx(_
("Unable to get the epoch value from the kernel."));
else
@ -1279,11 +1279,6 @@ static void usage(const struct hwclock_control *ctl, const char *fmt, ...)
" the default is %1$s\n"), _PATH_ADJTIME);
fputs(_(" --test do not update anything, just show what would happen\n"
" -D, --debug debugging mode\n" "\n"), usageto);
#ifdef __alpha__
fputs(_(" -J|--jensen, -A|--arc, -S|--srm, -F|--funky-toy\n"
" tell hwclock the type of Alpha you have (see hwclock(8))\n"
"\n"), usageto);
#endif
if (fmt) {
va_start(ap, fmt);
@ -1344,15 +1339,6 @@ int main(int argc, char **argv)
{ "version", no_argument, NULL, 'v' },
{ "systohc", no_argument, NULL, 'w' },
{ "debug", no_argument, NULL, 'D' },
#ifdef __alpha__
{ "ARC", no_argument, NULL, 'A' },
{ "arc", no_argument, NULL, 'A' },
{ "Jensen", no_argument, NULL, 'J' },
{ "jensen", no_argument, NULL, 'J' },
{ "SRM", no_argument, NULL, 'S' },
{ "srm", no_argument, NULL, 'S' },
{ "funky-toy", no_argument, NULL, 'F' },
#endif
{ "set", no_argument, NULL, OPT_SET },
#ifdef __linux__
{ "getepoch", no_argument, NULL, OPT_GETEPOCH },
@ -1438,20 +1424,6 @@ int main(int argc, char **argv)
case 'w':
ctl.systohc = 1;
break;
#ifdef __alpha__
case 'A':
ctl.ARCconsole = 1;
break;
case 'J':
ctl.Jensen = 1;
break;
case 'S':
ctl.SRM = 1;
break;
case 'F':
ctl.funky_toy = 1;
break;
#endif
case OPT_SET:
ctl.set = 1;
break;
@ -1538,10 +1510,6 @@ int main(int argc, char **argv)
"either --utc or --localtime"));
hwclock_exit(&ctl, EX_USAGE);
}
#ifdef __alpha__
set_cmos_epoch(&ctl);
set_cmos_access(&ctl);
#endif
if (ctl.set || ctl.predict) {
if (parse_date(&when, ctl.date_opt, NULL))

View File

@ -32,12 +32,6 @@ struct hwclock_control {
hctosys:1,
utc:1,
systohc:1,
#ifdef __alpha__
ARCconsole:1,
Jensen:1,
SRM:1,
funky_toy:1,
#endif
#ifdef __linux__
getepoch:1,
setepoch:1,
@ -71,12 +65,9 @@ typedef int bool;
extern int debug;
extern unsigned long epoch_option;
extern double time_diff(struct timeval subtrahend, struct timeval subtractor);
/* cmos.c */
extern void set_cmos_epoch(const struct hwclock_control *ctl);
extern void set_cmos_access(const struct hwclock_control *ctl);
/* rtc.c */
extern int get_epoch_rtc(const struct hwclock_control *ctl, unsigned long *epoch, int silent);
extern int get_epoch_rtc(const struct hwclock_control *ctl, unsigned long *epoch);
extern int set_epoch_rtc(const struct hwclock_control *ctl);
extern void hwclock_exit(const struct hwclock_control *ctl, int status);