Hello Klaus and Jim, On Saturday, February 2, 2008 at 14:02:23 +0100, Klaus Ethgen wrote:
> /dev/rtc doesn't allow user access to update interrupts > - using busy wait instead Understood: This is printed when ioctl(RTC_UIE_ON) fails, because the kernel driver thinks that the interrupt is not available. Adjtimex 1.23 has a fallback for this case: it calls busy_wait() in the intent to sync on UIP fall (instead of interrupt). Problem: the implementation of busy_wait() doesn't work in this case. Busy_wait() depends on using_dev_rtc=0, it depends on cmos_fd=/dev/port, and perhaps on other minor things. While Klaus is trying to use /dev/rtc default access mode, where using_dev_rtc=1 and cmos_fd=/dev/rtc. > lseek(3, 112, SEEK_SET) = -1 ESPIPE (Illegal seek) > write(3, "\212", 1) = -1 EBADF (Bad file descriptor) Of course, seeking direct access to IO ports 0x70 and 0x71 via a /dev/rtc device not done for this can only miserably fail. I see 3 possible solutions: -1) Rewrite busy_wait() to make it work in whatever using_dev_rtc mode, decouple cmos_fd for rtc and port, and fix some other minor probs. -2) When ioctl(RTC_UIE_ON) fails, close /dev/rtc, reset using_dev_rtc to 0, call again cmos_init(), and repeat the whole cmos_read_time() as if we were in --directisa mode all the time. -3) Rename busy_wait() to busywait_uip_fall() only for --directisa mode. Write a new busywait_second_change() function only for /dev/rtc mode, looping around ioctl(RTC_RD_TIME) until the time changes. Solution (1) is easy, quick, and dirty. I'm not really comfortable with mixing clean device access thru a driver, and dirty hack direct IO (even if it's not really directly, but thru /dev/port). Solution (2) is full direct IO. Dirty, but at least self-coherant. Solution (3) is clean: full /dev/rtc, self-coherant. The sync accuracy is rather good, only very little less than --directisa. Some low tens of microseconds delay on recent kernels since 2.6.16 (I measured the tick only 15 to 39 µs late on my dead old and slow machine). However the method steps on a bug of all previous kernels until 2.6.15, bug introducing a random error between 8000 and 18000 microseconds (ouch!). In the same no-interrupt fallback case, hwclock 2.31 uses method (3). And it has a --nointerrupt option to force this mode even outside of the fallback case. Before looking closely at the code, I'd seem to tend to prefer method (3). What's your opinion James? Alain.