コード例 #1
0
ファイル: hwclock-rtc.c プロジェクト: karelzak/util-linux
/*
 * Same as synchronize_to_clock_tick(), but just for /dev/rtc.
 */
static int synchronize_to_clock_tick_rtc(const struct hwclock_control *ctl)
{
	int rtc_fd;		/* File descriptor of /dev/rtc */
	int ret = 1;

	rtc_fd = open_rtc(ctl);
	if (rtc_fd == -1) {
		warn(_("cannot open rtc device"));
		return ret;
	} else {
		/* Turn on update interrupts (one per second) */
		int rc = ioctl(rtc_fd, RTC_UIE_ON, 0);

		if (rc != -1) {
			/*
			 * Just reading rtc_fd fails on broken hardware: no
			 * update interrupt comes and a bootscript with a
			 * hwclock call hangs
			 */
			fd_set rfds;
			struct timeval tv;

			/*
			 * Wait up to ten seconds for the next update
			 * interrupt
			 */
			FD_ZERO(&rfds);
			FD_SET(rtc_fd, &rfds);
			tv.tv_sec = 10;
			tv.tv_usec = 0;
			rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
			if (0 < rc)
				ret = 0;
			else if (rc == 0) {
				warnx(_("select() to %s to wait for clock tick timed out"),
				      rtc_dev_name);
			} else
				warn(_("select() to %s to wait for clock tick failed"),
				     rtc_dev_name);
			/* Turn off update interrupts */
			rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
			if (rc == -1)
				warn(_("ioctl() to %s to turn off update interrupts failed"),
				     rtc_dev_name);
		} else if (errno == ENOTTY || errno == EINVAL) {
			/* rtc ioctl interrupts are unimplemented */
			ret = busywait_for_rtc_clock_tick(ctl, rtc_fd);
		} else
			warn(_("ioctl(%d, RTC_UIE_ON, 0) to %s failed"),
			     rtc_fd, rtc_dev_name);
	}
	return ret;
}
コード例 #2
0
ファイル: hwclock-rtc.c プロジェクト: Flameeyes/util-linux
/*
 * Same as synchronize_to_clock_tick(), but just for /dev/rtc.
 */
static int synchronize_to_clock_tick_rtc(void)
{
	int rtc_fd;		/* File descriptor of /dev/rtc */
	int ret;

	rtc_fd = open_rtc();
	if (rtc_fd == -1) {
		warn(_("cannot open %s"), rtc_dev_name);
		ret = 1;
	} else {
		int rc;		/* Return code from ioctl */
		/* Turn on update interrupts (one per second) */
#if defined(__alpha__) || defined(__sparc__)
		/*
		 * Not all alpha kernels reject RTC_UIE_ON, but probably
		 * they should.
		 */
		rc = -1;
		errno = EINVAL;
#else
		rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
#endif
		if (rc == -1 && (errno == ENOTTY || errno == EINVAL)) {
			/*
			 * This rtc device doesn't have interrupt functions.
			 * This is typical on an Alpha, where the Hardware
			 * Clock interrupts are used by the kernel for the
			 * system clock, so aren't at the user's disposal.
			 */
			if (debug)
				printf(_
				       ("%s does not have interrupt functions. "),
				       rtc_dev_name);
			ret = busywait_for_rtc_clock_tick(rtc_fd);
		} else if (rc == 0) {
#ifdef Wait_until_update_interrupt
			unsigned long dummy;

			/* this blocks until the next update interrupt */
			rc = read(rtc_fd, &dummy, sizeof(dummy));
			ret = 1;
			if (rc == -1)
				warn(_
				     ("read() to %s to wait for clock tick failed"),
				     rtc_dev_name);
			else
				ret = 0;
#else
			/*
			 * Just reading rtc_fd fails on broken hardware: no
			 * update interrupt comes and a bootscript with a
			 * hwclock call hangs
			 */
			fd_set rfds;
			struct timeval tv;

			/*
			 * Wait up to ten seconds for the next update
			 * interrupt
			 */
			FD_ZERO(&rfds);
			FD_SET(rtc_fd, &rfds);
			tv.tv_sec = 10;
			tv.tv_usec = 0;
			rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
			ret = 1;
			if (rc == -1)
				warn(_
				     ("select() to %s to wait for clock tick failed"),
				     rtc_dev_name);
			else if (rc == 0)
				warn(_
				     ("select() to %s to wait for clock tick timed out"),
				     rtc_dev_name);
			else
				ret = 0;
#endif

			/* Turn off update interrupts */
			rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
			if (rc == -1)
				warn(_
				     ("ioctl() to %s to turn off update interrupts failed"),
				     rtc_dev_name);
		} else {
			warn(_
			     ("ioctl() to %s to turn on update interrupts "
			      "failed unexpectedly"), rtc_dev_name);
			ret = 1;
		}
	}
	return ret;
}