Revision a01cc6570326c01e70619bf6540fb32139947c33 authored by David Brownell on 04 July 2008, 16:59:26 UTC, committed by Linus Torvalds on 04 July 2008, 17:40:04 UTC
While 0e36a9a4a788e4e92407774df76c545910810d35 ("rtc: fix readback from
/sys/class/rtc/rtc?/wakealarm") made sure that active alarms were never
returned with invalid "wildcard" fields (negative), it can still report
(wrongly) that the alarm triggers in the past.

Example, if it's now 10am, an alarm firing at 5am will be triggered
TOMORROW not today.  (Which may also be next month or next year...)

This updates that alarm handling in three ways:

  * Handle alarm rollover in the common cases of RTCs that don't
    support matching on all date fields.

  * Skip the invalid-field logic when it's not needed.

  * Minor bugfix ... tm_isdst should be ignored, it's one of the
    fields Linux doesn't maintain.

A warning is emitted for some of the unhandled rollover cases, but the
possible combinations are a bit too numerous to handle every bit of
potential hardware and firmware braindamage.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Mark Lord <lkml@rtr.ca>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 251b97f
Raw File
gen_crc32table.c
#include <stdio.h>
#include "crc32defs.h"
#include <inttypes.h>

#define ENTRIES_PER_LINE 4

#define LE_TABLE_SIZE (1 << CRC_LE_BITS)
#define BE_TABLE_SIZE (1 << CRC_BE_BITS)

static uint32_t crc32table_le[LE_TABLE_SIZE];
static uint32_t crc32table_be[BE_TABLE_SIZE];

/**
 * crc32init_le() - allocate and initialize LE table data
 *
 * crc is the crc of the byte i; other entries are filled in based on the
 * fact that crctable[i^j] = crctable[i] ^ crctable[j].
 *
 */
static void crc32init_le(void)
{
	unsigned i, j;
	uint32_t crc = 1;

	crc32table_le[0] = 0;

	for (i = 1 << (CRC_LE_BITS - 1); i; i >>= 1) {
		crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
		for (j = 0; j < LE_TABLE_SIZE; j += 2 * i)
			crc32table_le[i + j] = crc ^ crc32table_le[j];
	}
}

/**
 * crc32init_be() - allocate and initialize BE table data
 */
static void crc32init_be(void)
{
	unsigned i, j;
	uint32_t crc = 0x80000000;

	crc32table_be[0] = 0;

	for (i = 1; i < BE_TABLE_SIZE; i <<= 1) {
		crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
		for (j = 0; j < i; j++)
			crc32table_be[i + j] = crc ^ crc32table_be[j];
	}
}

static void output_table(uint32_t table[], int len, char *trans)
{
	int i;

	for (i = 0; i < len - 1; i++) {
		if (i % ENTRIES_PER_LINE == 0)
			printf("\n");
		printf("%s(0x%8.8xL), ", trans, table[i]);
	}
	printf("%s(0x%8.8xL)\n", trans, table[len - 1]);
}

int main(int argc, char** argv)
{
	printf("/* this file is generated - do not edit */\n\n");

	if (CRC_LE_BITS > 1) {
		crc32init_le();
		printf("static const u32 crc32table_le[] = {");
		output_table(crc32table_le, LE_TABLE_SIZE, "tole");
		printf("};\n");
	}

	if (CRC_BE_BITS > 1) {
		crc32init_be();
		printf("static const u32 crc32table_be[] = {");
		output_table(crc32table_be, BE_TABLE_SIZE, "tobe");
		printf("};\n");
	}

	return 0;
}
back to top