diff options
author | bde <bde@FreeBSD.org> | 2007-03-05 09:10:17 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 2007-03-05 09:10:17 +0000 |
commit | f4efd01f602e7d460090e10e4cca9e3c349e39a4 (patch) | |
tree | b0b2b202d9a01ca712c8c2472d8465e88ca1bcf2 | |
parent | 914d3ae38712a1c29d4651be96661fe4c36cfab0 (diff) | |
download | FreeBSD-src-f4efd01f602e7d460090e10e4cca9e3c349e39a4.zip FreeBSD-src-f4efd01f602e7d460090e10e4cca9e3c349e39a4.tar.gz |
Partial fix for a bug in rev.1.231. If suspend/resume clobbers the
RTC state, then it may clobber the RTC index register, so the index
register must be restored before using it to restore control registers
in rtc_restore().
The following problems remain:
- rtc_restore() is only called if pmtimer is configured. Buggy
suspend/resumes are more likely to clobber the index register than
a control register, so pmtimer is more needed than it used to be.
- pmtimer doesn't exist for amd64.
- Restoring of the RTC state may race with rtcintr(). If an RTC
interrupt is handled before the state is restored, then rtcin(RTC_INTR)
in rtcintr() may read from the wrong register, so rtcintr() may spin
forever. This may be mitigated by the most common state clobbering
being to turn off RTC interrupts.
-rw-r--r-- | sys/i386/isa/clock.c | 1 | ||||
-rw-r--r-- | sys/isa/atrtc.c | 1 |
2 files changed, 2 insertions, 0 deletions
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index f2de4f5..3125bd1 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -579,6 +579,7 @@ rtc_restore(void) /* Restore all of the RTC's "status" (actually, control) registers. */ /* XXX locking is needed for RTC access. */ + rtc_reg = -1; writertc(RTC_STATUSB, RTCSB_24HR); writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, rtc_statusb); diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index f2de4f5..3125bd1 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -579,6 +579,7 @@ rtc_restore(void) /* Restore all of the RTC's "status" (actually, control) registers. */ /* XXX locking is needed for RTC access. */ + rtc_reg = -1; writertc(RTC_STATUSB, RTCSB_24HR); writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, rtc_statusb); |