From: Hans de Goede Date: Tue, 15 Aug 2006 10:09:27 +0000 (+0200) Subject: [PATCH] PATCH: 1 line 2.6.18 bugfix: modpost-64bit-fix.patch X-Git-Tag: v2.6.18-rc5~81 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e0e92632715f08dddeddb72b76e04c20126e1f67;p=linux-2.6 [PATCH] PATCH: 1 line 2.6.18 bugfix: modpost-64bit-fix.patch There is a small but annoying bug in scripts/mod/file2alias.c which causes it to generate invalid aliases for input devices on 64 bit archs. This causes joydev.ko to not be automaticly loaded when inserting a joystick, resulting in a non working joystick (for the average user). In scripts/mod/file2alias.c is the following code for generating the input aliases: static void do_input(char *alias, kernel_ulong_t *arr, unsigned int min, unsigned int max) { unsigned int i; for (i = min; i < max; i++) if (arr[i / BITS_PER_LONG] & (1 << (i%BITS_PER_LONG))) sprintf(alias + strlen(alias), "%X,*", i); } On 32 bits systems, this correctly generates "0,*" for the first alias, "8,*" for the second etc. However on 64 bits it generates: "0,*20,*" resp "8,*28,*" Notice how it adds 20 + first entry (hex) ! to the list of hex codes, which is 32 more then the first entry, thus is because the bit test above wraps at 32 bits instead of 64. scripts/mod/file2alias.c, line 379 reads: if (arr[i / BITS_PER_LONG] & (1 << (i%BITS_PER_LONG))) That should be: if (arr[i / BITS_PER_LONG] & (1L << (i%BITS_PER_LONG))) Notice the added 'L' after the 1, otherwise that is an 32 bit int instead of a 64 bit long, and when that int gets shifted >= 32 times, appearantly the number by which to shift is wrapped at 5 bits ( % 32) causing it to test a bit 32 bits too low. The patch below makes the nescesarry 1 char change :) Signed-off-by: Hans de Goede Acked-by: Rusty Russell Signed-off-by: Greg Kroah-Hartman --- diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 44312926b8..e2de650d3d 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -391,7 +391,7 @@ static void do_input(char *alias, unsigned int i; for (i = min; i < max; i++) - if (arr[i / BITS_PER_LONG] & (1 << (i%BITS_PER_LONG))) + if (arr[i / BITS_PER_LONG] & (1L << (i%BITS_PER_LONG))) sprintf(alias + strlen(alias), "%X,*", i); }