diff options
author | Gary Mills <gary_mills@fastmail.fm> | 2018-01-17 15:41:08 -0600 |
---|---|---|
committer | Dan McDonald <danmcd@joyent.com> | 2018-01-24 11:32:10 -0500 |
commit | 4414ceb126491c1abe47e693790eca5915a15fca (patch) | |
tree | d97bffa58bdb02776c7123fc9ebc5562ef87f377 | |
parent | a6c1eb3c08094a6db69aa1dc6315bc814e82e79c (diff) | |
download | illumos-joyent-4414ceb126491c1abe47e693790eca5915a15fca.tar.gz |
8680 Time of Day clock error
Reviewed by: Yuri Pankov <yuripv@icloud.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r-- | usr/src/uts/i86pc/io/todpc_subr.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/usr/src/uts/i86pc/io/todpc_subr.c b/usr/src/uts/i86pc/io/todpc_subr.c index 51bf1804d2..19042d49b7 100644 --- a/usr/src/uts/i86pc/io/todpc_subr.c +++ b/usr/src/uts/i86pc/io/todpc_subr.c @@ -19,6 +19,7 @@ * CDDL HEADER END */ /* + * Copyright 2018 Gary Mills * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* @@ -46,6 +47,7 @@ #include <sys/lockstat.h> #include <sys/stat.h> #include <sys/sunddi.h> +#include <sys/ddi.h> #include <sys/acpi/acpi.h> #include <sys/acpica.h> @@ -88,7 +90,8 @@ static struct rtc_offset pc_rtc_offset = {0, 0, 0, 0}; * are useful to TOD. */ void -pc_tod_set_rtc_offsets(ACPI_TABLE_FADT *fadt) { +pc_tod_set_rtc_offsets(ACPI_TABLE_FADT *fadt) +{ int ok = 0; /* @@ -330,7 +333,9 @@ todpc_clralarm(tod_ops_t *top) * Routine to read contents of real time clock to the specified buffer. * Returns ENXIO if clock not valid, or EAGAIN if clock data cannot be read * else 0. - * The routine will busy wait for the Update-In-Progress flag to clear. + * Some RTC hardware is very slow at asserting the validity flag on + * startup. The routine will busy wait for the RTC to become valid. + * The routine will also busy wait for the Update-In-Progress flag to clear. * On completion of the reads the Seconds register is re-read and the * UIP flag is rechecked to confirm that an clock update did not occur * during the accesses. Routine will error exit after 256 attempts. @@ -344,7 +349,8 @@ todpc_rtcget(unsigned char *buf) { unsigned char reg; int i; - int retries = 256; + int uip_try = 256; + int vrt_try = 512; unsigned char *rawp; unsigned char century = RTC_CENTURY; unsigned char day_alrm; @@ -358,13 +364,19 @@ todpc_rtcget(unsigned char *buf) century = pc_rtc_offset.century; } - outb(RTC_ADDR, RTC_D); /* check if clock valid */ - reg = inb(RTC_DATA); - if ((reg & RTC_VRT) == 0) - return (ENXIO); + for (;;) { + if (vrt_try-- < 0) + return (ENXIO); + outb(RTC_ADDR, RTC_D); /* check if clock valid */ + reg = inb(RTC_DATA); + if ((reg & RTC_VRT) != 0) + break; + drv_usecwait(5000); /* Delay for 5000 us */ + } + checkuip: - if (retries-- < 0) + if (uip_try-- < 0) return (EAGAIN); outb(RTC_ADDR, RTC_A); /* check if update in progress */ reg = inb(RTC_DATA); |