Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753401AbYLARBR (ORCPT ); Mon, 1 Dec 2008 12:01:17 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752075AbYLARBB (ORCPT ); Mon, 1 Dec 2008 12:01:01 -0500 Received: from rtr.ca ([76.10.145.34]:42955 "EHLO mail.rtr.ca" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751884AbYLARBA (ORCPT ); Mon, 1 Dec 2008 12:01:00 -0500 Message-ID: <4934188E.6080701@rtr.ca> Date: Mon, 01 Dec 2008 12:02:06 -0500 From: Mark Lord Organization: Real-Time Remedies Inc. User-Agent: Thunderbird 2.0.0.18 (X11/20081125) MIME-Version: 1.0 To: Len Brown , Alessandro Zummo Cc: David Brownell , lkml , rtc-linux@googlegroups.com, linux-acpi@vger.kernel.org Subject: Re: PATCH: /proc/acpi/alarm: handle day-of-month wraparound on readback References: <200806222042.13929.david-b@pacbell.net> <4934176F.6080900@rtr.ca> In-Reply-To: <4934176F.6080900@rtr.ca> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4212 Lines: 124 Mark Lord wrote: > Fix month wrap issue with readback from /proc/acpi/alarm > This bug has been around *forever*. > > $ echo '2008-12-01 10:36:20' > /proc/acpi/alarm > $ cat /proc/acpi/alarm > 2008-11-01 10:36:20 > > Note how the readback above shows the month incorrectly. > But with this patch applied, it shows the correct month (12). .. I should add, that the above test requires that the alarm be set for any day of the *next* month from the current month. My MythTV box does a readback test any time it programs a wakeup, and noticed the bug over this past weekend (2008-11-30). > > Patch applies/works on kernels 2.6.25.* through 2.6.27.*, > and probably on earlier kernels as well. > > Probably best to queue it up for the next major cycle. > > Signed-off-by: Mark Lord > > --- linux-2.6.25/drivers/acpi/sleep/proc.c 2008-06-09 > 14:27:19.000000000 -0400 > +++ linux/drivers/acpi/sleep/proc.c 2008-11-30 18:08:31.000000000 -0500 > @@ -84,12 +84,15 @@ > #define HAVE_ACPI_LEGACY_ALARM > #endif > > +static u32 cmos_bcd_read(int offset, int rtc_control); > + > #ifdef HAVE_ACPI_LEGACY_ALARM > > static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) > { > u32 sec, min, hr; > u32 day, mo, yr, cent = 0; > + u32 today = 0; > unsigned char rtc_control = 0; > unsigned long flags; > > @@ -97,38 +100,32 @@ > > spin_lock_irqsave(&rtc_lock, flags); > > - sec = CMOS_READ(RTC_SECONDS_ALARM); > - min = CMOS_READ(RTC_MINUTES_ALARM); > - hr = CMOS_READ(RTC_HOURS_ALARM); > rtc_control = CMOS_READ(RTC_CONTROL); > + sec = cmos_bcd_read(RTC_SECONDS_ALARM, rtc_control); > + min = cmos_bcd_read(RTC_MINUTES_ALARM, rtc_control); > + hr = cmos_bcd_read(RTC_HOURS_ALARM, rtc_control); > > /* If we ever get an FACP with proper values... */ > - if (acpi_gbl_FADT.day_alarm) > + if (acpi_gbl_FADT.day_alarm) { > /* ACPI spec: only low 6 its should be cared */ > day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F; > - else > - day = CMOS_READ(RTC_DAY_OF_MONTH); > + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) > + BCD_TO_BIN(day); > + } else > + day = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); > if (acpi_gbl_FADT.month_alarm) > - mo = CMOS_READ(acpi_gbl_FADT.month_alarm); > - else > - mo = CMOS_READ(RTC_MONTH); > + mo = cmos_bcd_read(acpi_gbl_FADT.month_alarm, rtc_control); > + else { > + mo = cmos_bcd_read(RTC_MONTH, rtc_control); > + today = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); > + } > if (acpi_gbl_FADT.century) > - cent = CMOS_READ(acpi_gbl_FADT.century); > + cent = cmos_bcd_read(acpi_gbl_FADT.century, rtc_control); > > - yr = CMOS_READ(RTC_YEAR); > + yr = cmos_bcd_read(RTC_YEAR, rtc_control); > > spin_unlock_irqrestore(&rtc_lock, flags); > > - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { > - BCD_TO_BIN(sec); > - BCD_TO_BIN(min); > - BCD_TO_BIN(hr); > - BCD_TO_BIN(day); > - BCD_TO_BIN(mo); > - BCD_TO_BIN(yr); > - BCD_TO_BIN(cent); > - } > - > /* we're trusting the FADT (see above) */ > if (!acpi_gbl_FADT.century) > /* If we're not trusting the FADT, we should at least make it > @@ -153,6 +150,20 @@ > else > yr += cent * 100; > > + /* > + * Show correct dates for alarms up to a month into the future. > + * This solves issues for nearly all situations with the common > + * 30-day alarm clocks in PC hardware. > + */ > + if (day < today) { > + if (mo < 12) { > + mo += 1; > + } else { > + mo = 1; > + yr += 1; > + } > + } > + > seq_printf(seq, "%4.4u-", yr); > (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); > (day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/