From ef71b8f1128b72bf072f1bd0a306b1bb06781a40 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sun, 24 Jul 2011 17:35:43 +0200 Subject: hwclock: coding style clean up Despide amount of the change this change should be harmless. Everything is about indendation, comment restructuring etc not code changes. Signed-off-by: Sami Kerola --- hwclock/cmos.c | 979 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 510 insertions(+), 469 deletions(-) (limited to 'hwclock/cmos.c') diff --git a/hwclock/cmos.c b/hwclock/cmos.c index 0178ef7d3..d6216717f 100644 --- a/hwclock/cmos.c +++ b/hwclock/cmos.c @@ -1,47 +1,48 @@ /* - * i386 CMOS starts out with 14 bytes clock data - * alpha has something similar, but with details - * depending on the machine type. + * i386 CMOS starts out with 14 bytes clock data alpha has something + * similar, but with details depending on the machine type. * - * byte 0: seconds (0-59) - * byte 2: minutes (0-59) - * byte 4: hours (0-23 in 24hr mode, - * 1-12 in 12hr mode, with high bit unset/set if am/pm) - * byte 6: weekday (1-7, Sunday=1) - * byte 7: day of the month (1-31) - * byte 8: month (1-12) - * byte 9: year (0-99) - * Numbers are stored in BCD/binary if bit 2 of byte 11 is unset/set - * The clock is in 12hr/24hr mode if bit 1 of byte 11 is unset/set - * The clock is undefined (being updated) if bit 7 of byte 10 is set. - * The clock is frozen (to be updated) by setting bit 7 of byte 11 - * Bit 7 of byte 14 indicates whether the CMOS clock is reliable: - * it is 1 if RTC power has been good since this bit was last read; - * it is 0 when the battery is dead and system power has been off. + * byte 0: seconds 0-59 + * byte 2: minutes 0-59 + * byte 4: hours 0-23 in 24hr mode, + * 1-12 in 12hr mode, with high bit unset/set + * if am/pm. + * byte 6: weekday 1-7, Sunday=1 + * byte 7: day of the month 1-31 + * byte 8: month 1-12 + * byte 9: year 0-99 * - * Avoid setting the RTC clock within 2 seconds of the day rollover - * that starts a new month or enters daylight saving time. + * Numbers are stored in BCD/binary if bit 2 of byte 11 is unset/set The + * clock is in 12hr/24hr mode if bit 1 of byte 11 is unset/set The clock is + * undefined (being updated) if bit 7 of byte 10 is set. The clock is frozen + * (to be updated) by setting bit 7 of byte 11 Bit 7 of byte 14 indicates + * whether the CMOS clock is reliable: it is 1 if RTC power has been good + * since this bit was last read; it is 0 when the battery is dead and system + * power has been off. + * + * Avoid setting the RTC clock within 2 seconds of the day rollover that + * starts a new month or enters daylight saving time. * * The century situation is messy: - * Usually byte 50 (0x32) gives the century (in BCD, so 19 or 20 hex), - * but IBM PS/2 has (part of) a checksum there and uses byte 55 (0x37). - * Sometimes byte 127 (0x7f) or Bank 1, byte 0x48 gives the century. - * The original RTC will not access any century byte; some modern - * versions will. If a modern RTC or BIOS increments the century byte - * it may go from 0x19 to 0x20, but in some buggy cases 0x1a is produced. + * + * Usually byte 50 (0x32) gives the century (in BCD, so 19 or 20 hex), but + * IBM PS/2 has (part of) a checksum there and uses byte 55 (0x37). + * Sometimes byte 127 (0x7f) or Bank 1, byte 0x48 gives the century. The + * original RTC will not access any century byte; some modern versions will. + * If a modern RTC or BIOS increments the century byte it may go from 0x19 + * to 0x20, but in some buggy cases 0x1a is produced. */ - /* * A struct tm has int fields - * tm_sec (0-59, 60 or 61 only for leap seconds) - * tm_min (0-59) - * tm_hour (0-23) - * tm_mday (1-31) - * tm_mon (0-11) - * tm_year (number of years since 1900) - * tm_wday (0-6, 0=Sunday) - * tm_yday (0-365) - * tm_isdst (>0: yes, 0: no, <0: unknown) + * tm_sec 0-59, 60 or 61 only for leap seconds + * tm_min 0-59 + * tm_hour 0-23 + * tm_mday 1-31 + * tm_mon 0-11 + * tm_year number of years since 1900 + * tm_wday 0-6, 0=Sunday + * tm_yday 0-365 + * tm_isdst >0: yes, 0: no, <0: unknown */ #include /* for geteuid() */ @@ -50,27 +51,40 @@ #include "nls.h" #if defined(__i386__) - # ifdef HAVE_SYS_IO_H -# include +# include # elif defined(HAVE_ASM_IO_H) -# include /* for inb, outb */ +# include /* for inb, outb */ # else -/* Disable cmos access; we can no longer use asm/io.h, since - * the kernel does not export that header. */ -# undef __i386__ -void outb(int a, int b){} -int inb(int c){ return 0; } -# endif +/* + * Disable cmos access; we can no longer use asm/io.h, since the kernel does + * not export that header. + */ +#undef __i386__ +void outb(int a, int b) +{ +} + +int inb(int c) +{ + return 0; +} +#endif /* __i386__ */ #elif defined(__alpha__) /* 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 unsigned int inb(unsigned long port); +extern void outb(unsigned char b, unsigned long port); #else -void outb(int a, int b){} -int inb(int c){ return 0; } -#endif +void outb(int a, int b) +{ +} + +int inb(int c) +{ + return 0; +} +#endif /* __alpha__ */ #include "clock.h" @@ -80,39 +94,40 @@ int inb(int c){ return 0; } /* * 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. + * 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. */ #define TM_EPOCH 1900 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 beween "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. +/* + * Martin Ostermann writes: + * + * The problem with the Jensen is twofold: First, it has the clock at a + * different address. Secondly, it has a distinction beween "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. */ int use_dev_port = 0; /* 1 for Jensen */ int dev_port_fd; unsigned short clock_ctl_addr = 0x70; /* 0x170 for Jensen */ -unsigned short clock_data_addr = 0x71; /* 0x171 for Jensen */ - +unsigned short clock_data_addr = 0x71; /* 0x171 for Jensen */ int century_byte = 0; /* 0: don't access a century byte - 50 (0x32): usual PC value - 55 (0x37): PS/2 */ + * 50 (0x32): usual PC value + * 55 (0x37): PS/2 + */ #ifdef __alpha__ int funkyTOY = 0; /* 1 for PC164/LX164/SX164 type alpha */ @@ -120,217 +135,242 @@ int funkyTOY = 0; /* 1 for PC164/LX164/SX164 type alpha */ #ifdef __alpha -static int -is_in_cpuinfo(char *fmt, char *str) +static int is_in_cpuinfo(char *fmt, char *str) { - FILE *cpuinfo; - char field[256]; - char format[256]; - int found = 0; - - sprintf(format, "%s : %s", fmt, "%255s"); - - if ((cpuinfo = fopen ("/proc/cpuinfo", "r")) != NULL) { - while (!feof(cpuinfo)) { - if (fscanf (cpuinfo, format, field) == 1) { - if (strncmp(field, str, strlen(str)) == 0) - found = 1; - break; - } - fgets (field, 256, cpuinfo); + FILE *cpuinfo; + char field[256]; + char format[256]; + int found = 0; + + sprintf(format, "%s : %s", fmt, "%255s"); + + if ((cpuinfo = fopen("/proc/cpuinfo", "r")) != NULL) { + while (!feof(cpuinfo)) { + if (fscanf(cpuinfo, format, field) == 1) { + if (strncmp(field, str, strlen(str)) == 0) + found = 1; + break; + } + fgets(field, 256, cpuinfo); + } + fclose(cpuinfo); } - fclose(cpuinfo); - } - return found; + 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(int ARCconsole, int SRM) { - unsigned long epoch; - - /* Believe the user */ - if (epoch_option != -1) { - cmos_epoch = epoch_option; - return; - } +/* + * Set cmos_epoch, either from user options, or by asking the kernel, or by + * looking at /proc/cpu_info + */ +void set_cmos_epoch(int ARCconsole, int SRM) +{ + unsigned long epoch; - if (ARCconsole) - cmos_epoch = 1980; + /* Believe the user */ + if (epoch_option != -1) { + cmos_epoch = epoch_option; + return; + } - if (ARCconsole || SRM) - return; + if (ARCconsole) + cmos_epoch = 1980; + if (ARCconsole || SRM) + return; #ifdef __linux__ - /* If we can ask the kernel, we don't need guessing from /proc/cpuinfo */ - if (get_epoch_rtc(&epoch, 1) == 0) { - cmos_epoch = epoch; - return; - } + /* + * If we can ask the kernel, we don't need guessing from + * /proc/cpuinfo + */ + if (get_epoch_rtc(&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. - 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")) { - ARCconsole = 1; - if (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 (ARCconsole && is_in_cpuinfo("system type", "Ruffian")) { - ARCconsole = 0; - if (debug) printf (_("Ruffian BCD clock\n")); - } - - if (ARCconsole) - cmos_epoch = 1980; -} + /* + * 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")) { + ARCconsole = 1; + if (debug) + printf(_("booted from MILO\n")); + } -void -set_cmos_access(int Jensen, int funky_toy) { - - /* 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 (Jensen || is_in_cpuinfo("system type", "Jensen")) { - use_dev_port = 1; - clock_ctl_addr = 0x170; - clock_data_addr = 0x171; - if (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 (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 (debug) printf (_("funky TOY!\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 (ARCconsole && is_in_cpuinfo("system type", "Ruffian")) { + ARCconsole = 0; + if (debug) + printf(_("Ruffian BCD clock\n")); + } + + if (ARCconsole) + cmos_epoch = 1980; } -#endif +void set_cmos_access(int Jensen, int funky_toy) +{ + + /* + * 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 (Jensen || is_in_cpuinfo("system type", "Jensen")) { + use_dev_port = 1; + clock_ctl_addr = 0x170; + clock_data_addr = 0x171; + if (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 (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 (debug) + printf(_("funky TOY!\n")); + } +} +#endif /* __alpha */ #if __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. + * 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)(unsigned long), - unsigned long arg) +atomic(const char *name, unsigned long (*op) (unsigned long), unsigned long arg) { - unsigned long ts1, ts2, n, v; - - for (n = 0; n < 1000; ++n) { - asm volatile ("rpcc %0" : "r="(ts1)); - v = (*op)(arg); - asm volatile ("rpcc %0" : "r="(ts2)); - - if ((ts1 ^ ts2) >> 32 == 0) { - return v; - } - } - fprintf(stderr, _("%s: atomic %s failed for 1000 iterations!"), progname, name); - exit(1); + unsigned long ts1, ts2, n, v; + + for (n = 0; n < 1000; ++n) { + asm volatile ("rpcc %0":"r=" (ts1)); + v = (*op) (arg); + asm volatile ("rpcc %0":"r=" (ts2)); + + if ((ts1 ^ ts2) >> 32 == 0) { + return v; + } + } + fprintf(stderr, _("%s: atomic %s failed for 1000 iterations!"), + progname, name); + exit(1); } #else /* - * Hmmh, this isn't very atomic. Maybe we should force an error - * instead? + * 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 + * TODO: optimize the access to CMOS by mlockall(MCL_CURRENT) and SCHED_FIFO */ static unsigned long -atomic(const char *name, unsigned long (*op)(unsigned long), - unsigned long arg) +atomic(const char *name, unsigned long (*op) (unsigned long), unsigned long arg) { - return (*op)(arg); + return (*op) (arg); } #endif - -static inline -unsigned long cmos_read(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 && debug) - printf(_("cmos_read(): write to control address %X failed: %s\n"), clock_ctl_addr, strerror(errno)); - lseek(dev_port_fd, clock_data_addr, 0); - if (read(dev_port_fd, &v, 1) == -1 && debug) - printf(_("cmos_read(): read data address %X failed: %s\n"), clock_data_addr, strerror(errno)); - 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 wil be left in an unknown state". - Most docs say that it doesnt 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); - } + 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 && debug) + printf(_ + ("cmos_read(): write to control address %X failed: %s\n"), + clock_ctl_addr, strerror(errno)); + lseek(dev_port_fd, clock_data_addr, 0); + if (read(dev_port_fd, &v, 1) == -1 && debug) + printf(_ + ("cmos_read(): read data address %X failed: %s\n"), + clock_data_addr, strerror(errno)); + 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 wil be left in + * an unknown state". Most docs say that it doesnt 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); + } } -static inline -unsigned long cmos_write(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 && debug) - printf(_("cmos_write(): write to control address %X failed: %s\n"), clock_ctl_addr, strerror(errno)); - v = (val & 0xff); - lseek(dev_port_fd, clock_data_addr, 0); - if (write(dev_port_fd, &v, 1) == -1 && debug) - printf(_("cmos_write(): write to data address %X failed: %s\n"), clock_data_addr, strerror(errno)); - } else { - outb (reg, clock_ctl_addr); - outb (val, clock_data_addr); - } - return 0; + 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 && debug) + printf(_ + ("cmos_write(): write to control address %X failed: %s\n"), + clock_ctl_addr, strerror(errno)); + v = (val & 0xff); + lseek(dev_port_fd, clock_data_addr, 0); + if (write(dev_port_fd, &v, 1) == -1 && debug) + printf(_ + ("cmos_write(): write to data address %X failed: %s\n"), + clock_data_addr, strerror(errno)); + } else { + outb(reg, clock_ctl_addr); + outb(val, clock_data_addr); + } + return 0; } 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; + 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: @@ -349,260 +389,261 @@ static unsigned long cmos_set_time(unsigned long arg) * 1111 500 milliseconds (maximum, 2 Hz) * 0110 976.562 microseconds (default 1024 Hz) */ + 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; + + if (!(save_control & 0x02)) { /* 12hr mode; the default is 24hr mode */ + if (tm.tm_hour == 0) + tm.tm_hour = 24; + if (tm.tm_hour > 12) { + tm.tm_hour -= 12; + pmbit = 0x80; + } + } + + if (!(save_control & 0x04)) { /* BCD mode - the default */ + BIN_TO_BCD(tm.tm_sec); + BIN_TO_BCD(tm.tm_min); + BIN_TO_BCD(tm.tm_hour); + BIN_TO_BCD(tm.tm_wday); + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_mon); + BIN_TO_BCD(tm.tm_year); + BIN_TO_BCD(century); + } - 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; - - if (!(save_control & 0x02)) { /* 12hr mode; the default is 24hr mode */ - if (tm.tm_hour == 0) - tm.tm_hour = 24; - if (tm.tm_hour > 12) { - tm.tm_hour -= 12; - pmbit = 0x80; - } - } - - if (!(save_control & 0x04)) { /* BCD mode - the default */ - BIN_TO_BCD(tm.tm_sec); - BIN_TO_BCD(tm.tm_min); - BIN_TO_BCD(tm.tm_hour); - BIN_TO_BCD(tm.tm_wday); - BIN_TO_BCD(tm.tm_mday); - BIN_TO_BCD(tm.tm_mon); - BIN_TO_BCD(tm.tm_year); - BIN_TO_BCD(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); - if (century_byte) - cmos_write (century_byte, century); - - - /* The kernel sources, linux/arch/i386/kernel/time.c, have the - following comment: - - The following flags have to be released exactly in this order, - otherwise the DS12887 (popular MC146818A clone with integrated - battery and quartz) will not reset the oscillator and will not - update precisely 500 ms later. You won't find this mentioned - in the Dallas Semiconductor data sheets, but who believes data - sheets anyway ... -- Markus Kuhn - */ - - cmos_write (11, save_control); - cmos_write (10, save_freq_select); - return 0; + 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); + if (century_byte) + cmos_write(century_byte, century); + + /* + * The kernel sources, linux/arch/i386/kernel/time.c, have the + * following comment: + * + * The following flags have to be released exactly in this order, + * otherwise the DS12887 (popular MC146818A clone with integrated + * battery and quartz) will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned in + * the Dallas Semiconductor data sheets, but who believes data + * sheets anyway ... -- Markus Kuhn + */ + cmos_write(11, save_control); + cmos_write(10, save_freq_select); + return 0; } -static int -hclock_read(unsigned long reg) { +static int hclock_read(unsigned long reg) +{ return atomic("clock read", cmos_read, (reg)); } -static void -hclock_set_time(const struct tm *tm) { +static void hclock_set_time(const struct tm *tm) +{ atomic("set time", cmos_set_time, (unsigned long)(tm)); } -static inline int -cmos_clock_busy(void) { +static inline int cmos_clock_busy(void) +{ return #ifdef __alpha__ - /* poll bit 4 (UF) of Control Register C */ + /* poll bit 4 (UF) of Control Register C */ funkyTOY ? (hclock_read(12) & 0x10) : #endif - /* poll bit 7 (UIP) of Control Register A */ + /* poll bit 7 (UIP) of Control Register A */ (hclock_read(10) & 0x80); } - -static int -synchronize_to_clock_tick_cmos(void) { - int i; - - /* Wait for rise. Should be within a second, but in case something - weird happens, we have a limit on this loop to reduce the impact - of this failure. - */ - 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(); i++) - if (i >= 1000000) - return 1; - return 0; +static int synchronize_to_clock_tick_cmos(void) +{ + int i; + + /* + * Wait for rise. Should be within a second, but in case something + * weird happens, we have a limit on this loop to reduce the impact + * of this failure. + */ + 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(); i++) + if (i >= 1000000) + return 1; + return 0; } - - -static int -read_hardware_clock_cmos(struct tm *tm) { -/*---------------------------------------------------------------------------- - Read the hardware clock and return the current time via argument. - Assume we have an ISA machine and read the clock directly with CPU I/O - instructions. - - This function is not totally reliable. It takes a finite and - unpredictable amount of time to execute the code below. During that - time, the clock may change and we may even read an invalid value in - the middle of an update. We do a few checks to minimize this - possibility, but only the kernel can actually read the clock - properly, since it can execute code in a short and predictable - amount of time (by turning of interrupts). - - In practice, the chance of this function returning the wrong time is - extremely remote. - ------------------------------------------------------------------------------*/ - bool got_time = FALSE; - unsigned char status, pmbit; - - status = pmbit = 0; /* just for gcc */ - - while (!got_time) { - /* Bit 7 of Byte 10 of the Hardware Clock value is the Update In Progress - (UIP) bit, which is on while and 244 uS before the Hardware Clock - updates itself. It updates the counters individually, so reading - them during an update would produce garbage. The update takes 2mS, - so we could be spinning here that long waiting for this bit to turn - off. - - Furthermore, it is pathologically possible for us to be in this - code so long that even if the UIP bit is not on 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()) { - /* No clock update in progress, go ahead and read */ - 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); +/* + * Read the hardware clock and return the current time via argument. + * Assume we have an ISA machine and read the clock directly with CPU I/O + * instructions. + * + * This function is not totally reliable. It takes a finite and + * unpredictable amount of time to execute the code below. During that time, + * the clock may change and we may even read an invalid value in the middle + * of an update. We do a few checks to minimize this possibility, but only + * the kernel can actually read the clock properly, since it can execute + * code in a short and predictable amount of time (by turning of + * interrupts). + * + * In practice, the chance of this function returning the wrong time is + * extremely remote. + */ +static int read_hardware_clock_cmos(struct tm *tm) +{ + bool got_time = FALSE; + unsigned char status, pmbit; + + status = pmbit = 0; /* just for gcc */ + + while (!got_time) { + /* + * Bit 7 of Byte 10 of the Hardware Clock value is the + * Update In Progress (UIP) bit, which is on while and 244 + * uS before the Hardware Clock updates itself. It updates + * the counters individually, so reading them during an + * update would produce garbage. The update takes 2mS, so we + * could be spinning here that long waiting for this bit to + * turn off. + * + * Furthermore, it is pathologically possible for us to be + * in this code so long that even if the UIP bit is not on + * 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()) { + /* No clock update in progress, go ahead and read */ + 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); #if 0 - if (century_byte) - century = hclock_read(century_byte); + if (century_byte) + century = hclock_read(century_byte); #endif + /* + * Unless the clock changed while we were reading, + * consider this a good clock read . + */ + if (tm->tm_sec == hclock_read(0)) + got_time = TRUE; + } + /* + * Yes, in theory we could have been running for 60 seconds + * and the above test wouldn't work! + */ + } - /* Unless the clock changed while we were reading, consider this - a good clock read . - */ - if (tm->tm_sec == hclock_read (0)) - got_time = TRUE; - } - /* Yes, in theory we could have been running for 60 seconds and - the above test wouldn't work! - */ - } - - if (!(status & 0x04)) { /* BCD mode - the default */ - BCD_TO_BIN(tm->tm_sec); - BCD_TO_BIN(tm->tm_min); - pmbit = (tm->tm_hour & 0x80); - tm->tm_hour &= 0x7f; - BCD_TO_BIN(tm->tm_hour); - BCD_TO_BIN(tm->tm_wday); - BCD_TO_BIN(tm->tm_mday); - BCD_TO_BIN(tm->tm_mon); - BCD_TO_BIN(tm->tm_year); + if (!(status & 0x04)) { /* BCD mode - the default */ + BCD_TO_BIN(tm->tm_sec); + BCD_TO_BIN(tm->tm_min); + pmbit = (tm->tm_hour & 0x80); + tm->tm_hour &= 0x7f; + BCD_TO_BIN(tm->tm_hour); + BCD_TO_BIN(tm->tm_wday); + BCD_TO_BIN(tm->tm_mday); + BCD_TO_BIN(tm->tm_mon); + BCD_TO_BIN(tm->tm_year); #if 0 - BCD_TO_BIN(century); + BCD_TO_BIN(century); #endif - } - - /* We don't use the century byte of the Hardware Clock - since we don't know its address (usually 50 or 55). - Here, we follow the advice of the X/Open Base Working Group: - "if century is not specified, then values in the range [69-99] - refer to years in the twentieth century (1969 to 1999 inclusive), - and values in the range [00-68] refer to years in the twenty-first - century (2000 to 2068 inclusive)." - */ - - 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) { - tm->tm_hour += 12; - if (tm->tm_hour == 24) - tm->tm_hour = 0; - } - - tm->tm_isdst = -1; /* don't know whether it's daylight */ - return 0; -} + } + /* + * We don't use the century byte of the Hardware Clock since we + * don't know its address (usually 50 or 55). Here, we follow the + * advice of the X/Open Base Working Group: "if century is not + * specified, then values in the range [69-99] refer to years in the + * twentieth century (1969 to 1999 inclusive), and values in the + * range [00-68] refer to years in the twenty-first century (2000 to + * 2068 inclusive)." + */ + 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) { + tm->tm_hour += 12; + if (tm->tm_hour == 24) + tm->tm_hour = 0; + } + tm->tm_isdst = -1; /* don't know whether it's daylight */ + return 0; +} -static int -set_hardware_clock_cmos(const struct tm *new_broken_time) { +static int set_hardware_clock_cmos(const struct tm *new_broken_time) +{ - hclock_set_time(new_broken_time); - return 0; + hclock_set_time(new_broken_time); + return 0; } -static int -i386_iopl(const int level) { +static int i386_iopl(const int level) +{ #if defined(__i386__) || defined(__alpha__) #if defined(HAVE_IOPL) - extern int iopl(const int lvl); - return iopl(level); + extern int iopl(const int lvl); + return iopl(level); #else - extern int ioperm(unsigned long from, unsigned long num, int turn_on); - return ioperm(clock_ctl_addr, 2, 1); + extern int ioperm(unsigned long from, unsigned long num, int turn_on); + return ioperm(clock_ctl_addr, 2, 1); #endif #else - return -2; + return -2; #endif } -static int -get_permissions_cmos(void) { - int rc; - - if (use_dev_port) { - if ((dev_port_fd = open("/dev/port", O_RDWR)) < 0) { - int errsv = errno; - fprintf(stderr, _("Cannot open /dev/port: %s"), strerror(errsv)); - rc = 1; - } else - rc = 0; - } else { - rc = i386_iopl(3); - if (rc == -2) { - fprintf(stderr, _("I failed to get permission because I didn't try.\n")); - } else if (rc != 0) { - rc = errno; - fprintf(stderr, _("%s is unable to get I/O port access: " - "the iopl(3) call failed.\n"), progname); - if(rc == EPERM && geteuid()) - fprintf(stderr, _("Probably you need root privileges.\n")); - } - } - return rc ? 1 : 0; +static int get_permissions_cmos(void) +{ + int rc; + + if (use_dev_port) { + if ((dev_port_fd = open("/dev/port", O_RDWR)) < 0) { + int errsv = errno; + fprintf(stderr, _("Cannot open /dev/port: %s"), + strerror(errsv)); + rc = 1; + } else + rc = 0; + } else { + rc = i386_iopl(3); + if (rc == -2) { + fprintf(stderr, + _ + ("I failed to get permission because I didn't try.\n")); + } else if (rc != 0) { + rc = errno; + fprintf(stderr, + _("%s is unable to get I/O port access: " + "the iopl(3) call failed.\n"), progname); + if (rc == EPERM && geteuid()) + fprintf(stderr, + _ + ("Probably you need root privileges.\n")); + } + } + return rc ? 1 : 0; } static struct clock_ops cmos = { @@ -613,17 +654,17 @@ static struct clock_ops cmos = { synchronize_to_clock_tick_cmos, }; - -/* return &cmos if cmos clock present, NULL otherwise */ -/* choose this construction to avoid gcc messages about unused variables */ - -struct clock_ops * -probe_for_cmos_clock(void){ - int have_cmos = +/* + * return &cmos if cmos clock present, NULL otherwise choose this + * construction to avoid gcc messages about unused variables + */ +struct clock_ops *probe_for_cmos_clock(void) +{ + int have_cmos = #if defined(__i386__) || defined(__alpha__) TRUE; #else FALSE; #endif - return have_cmos ? &cmos : NULL; + return have_cmos ? &cmos : NULL; } -- cgit v1.2.3-55-g7522